Skip to content

Instantly share code, notes, and snippets.

@maht0rz
Created July 21, 2020 16:55
Show Gist options
  • Save maht0rz/cf190f58ed129477950b26cef0e4e977 to your computer and use it in GitHub Desktop.
Save maht0rz/cf190f58ed129477950b26cef0e4e977 to your computer and use it in GitHub Desktop.
const errorTokenUndefined = "FA2_TOKEN_UNDEFINED"
const errorInsufficientBalance = "FA2_INSUFFICIENT_BALANCE"
const errorNotOwner = "FA2_NOT_OWNER"
const errorTransferDenied = "FA2_TX_DENIED"
const errorOperatorsUnsupported = "FA2_OPERATORS_UNSUPPORTED"
const errorNotOperator = "FA2_NOT_OPERATOR"
const errorOperatorUpdateDenied = "FA2_OPERATOR_UPDATE_DENIED"
const errorReceiverHookFailed = "FA2_RECEIVER_HOOK_FAILED"
const errorSenderHookFailed = "FA2_SENDER_HOOK_FAILED"
const errorReceiverHookUndefined = "FA2_RECEIVER_HOOK_UNDEFINED"
const errorSenderHookUndefined = "FA2_SENDER_HOOK_UNDEFINED"
type tokenOwner = address
type tokenId = nat
type tokenAmount = nat
type tokenBalance = nat
type tokenOwner = address
type tokenId = nat
type tokenAmount = nat
type tokenBalance = nat
type tokenLookupId = ( tokenOwner * tokenId )
type tokensLedger = Big Map (tokenLookupId , tokenBalance)
type tokenOperator = address
type tokenOperatorsSet = set (tokenOperator)
type tokenOperators = Map (tokenOwner , tokenOperatorsSet)
type tokenSymbol = string
type tokenName = string
type tokenDecimals = nat
type tokenExtrasKey = string
type tokenExtrasValue = string
type tokenExtras = Map (tokenExtrasKey , tokenExtrasValue)
type tokenMetadata =
record[decimals -> tokenDecimals ,
extras -> tokenExtras ,
name -> tokenName ,
symbol -> tokenSymbol ,
token_id -> tokenId]
type tokenMetadataRegistry = Map (tokenId , tokenMetadata)
type storage =
record[tzip12 -> record[tokenOperators -> tokenOperators ,
tokensLedger -> tokensLedger ,
u -> unit] ,
u -> unit]
type operatorTransferPolicy =
sum[No_transfer -> unit ,
Owner_or_operator_transfer -> unit ,
Owner_transfer -> unit]
type ownerHookPolicy =
sum[Optional_owner_hook -> unit ,
Owner_no_hook -> unit ,
Required_owner_hook -> unit]
type customPermissionPolicy =
record[config_api -> option (address) , tag -> string]
type permissionsDescriptor =
record[custom -> option (customPermissionPolicy) ,
operator -> operatorTransferPolicy ,
receiver -> ownerHookPolicy ,
sender -> ownerHookPolicy]
type operatorUpdatePolicy =
sum[No_update -> unit ,
Owner_or_operator_update -> unit ,
Owner_update -> unit]
type tokenOwner = address
type tokenId = nat
type tokenAmount = nat
type tokenBalance = nat
type transferContents =
record[amount -> tokenAmount , to_ -> tokenOwner , token_id -> tokenId]
type transfer = record[from_ -> tokenOwner , txs -> list (transferContents)]
type transferContentsMichelson = michelson_pair_right_comb (transferContents)
type transferAuxiliary =
record[from_ -> tokenOwner , txs -> list (transferContentsMichelson)]
type transferMichelson = michelson_pair_right_comb (transferAuxiliary)
type transferParameter = list (transferMichelson)
const isOperator : ( tokenOwner * tokenOperator * storage ) -> bool =
lambda (#P:Some(( tokenOwner * tokenOperator * storage ))) : None return
let rhs#79 = #P in
let tokenOwner = rhs#79.0 in
let tokenOperator = rhs#79.1 in
let storage = rhs#79.2 in
let tokenOperatorsSet =
MAP_FIND_OP(tokenOwner , storage.tzip12.tokenOperators) : option (tokenOperatorsSet) in
match tokenOperatorsSet with
| None ->
false(unit)
| Some tokenOperatorsSet ->
SET_MEM(tokenOperator , tokenOperatorsSet)
const currentPermissionsDescriptor : permissionsDescriptor =
record[custom -> NONE() : option (customPermissionPolicy) ,
operator -> Owner_or_operator_transfer(unit) ,
receiver -> Owner_no_hook(unit) ,
sender -> Owner_no_hook(unit)]
const currentOperatorUpdatePermissionPolicy : operatorUpdatePolicy =
Owner_update(unit)
const canUpdateOperators : ( tokenOwner * storage ) -> unit =
lambda (#P:Some(( tokenOwner * storage ))) : None return
let rhs#81 = #P in
let tokenOwner = rhs#81.0 in
let storage = rhs#81.1 in
match NEQ(SENDER() , tokenOwner) with
| true _ -> FAILWITH(errorOperatorUpdateDenied) | false _ -> unit
const canTransfer : ( tokenOwner * transferContents * storage ) -> unit =
lambda (#P:Some(( tokenOwner * transferContents * storage ))) : None return
let rhs#82 = #P in
let from = rhs#82.0 in
let transferContents = rhs#82.1 in
let storage = rhs#82.2 in
match NEQ(from , SENDER()) with
| true _ ->
match NOT((isOperator)@(( from , SENDER() , storage ))) with
| true _ -> FAILWITH(errorNotOperator) | false _ -> unit
| false _ ->
unit
type tokenOwner = address
type tokenId = nat
type tokenAmount = nat
type tokenBalance = nat
type transferContents =
record[amount -> tokenAmount , to_ -> tokenOwner , token_id -> tokenId]
type transfer = record[from_ -> tokenOwner , txs -> list (transferContents)]
type transferContentsMichelson = michelson_pair_right_comb (transferContents)
type transferAuxiliary =
record[from_ -> tokenOwner , txs -> list (transferContentsMichelson)]
type transferMichelson = michelson_pair_right_comb (transferAuxiliary)
type transferParameter = list (transferMichelson)
type operatorTransferPolicyMichelson =
michelson_or_right_comb (operatorTransferPolicy)
type ownerHookPolicyMichelson = michelson_or_right_comb (ownerHookPolicy)
type customPermissionPolicyMichelson =
michelson_pair_right_comb (customPermissionPolicy)
type permissionsDescriptorAuxiliary =
record[custom -> option (customPermissionPolicyMichelson) ,
operator -> operatorTransferPolicyMichelson ,
receiver -> ownerHookPolicyMichelson ,
sender -> ownerHookPolicyMichelson]
type permissionsDescriptorMichelson =
michelson_pair_right_comb (permissionsDescriptorAuxiliary)
type permissionsDescriptorParameter =
Contract (permissionsDescriptorMichelson)
type balanceOfRequest = record[owner -> tokenOwner , token_id -> tokenId]
type balanceOfResponse =
record[balance -> tokenBalance , request -> balanceOfRequest]
type balanceOfCallback = Contract (list (balanceOfResponse))
type balanceOfParameter =
record[callback -> balanceOfCallback , requests -> list (balanceOfRequest)]
type balanceOfRequestMichelson = michelson_pair_right_comb (balanceOfRequest)
type balanceOfResponseAuxiliary =
record[balance -> tokenBalance , request -> balanceOfRequestMichelson]
type balanceOfResponseMichelson =
michelson_pair_right_comb (balanceOfResponseAuxiliary)
type balanceOfCallbackMichelson =
Contract (list (balanceOfResponseMichelson))
type balanceOfParameterAuxiliary =
record[callback -> balanceOfCallbackMichelson ,
requests -> list (balanceOfRequestMichelson)]
type balanceOfParameterMichelson =
michelson_pair_right_comb (balanceOfParameterAuxiliary)
type tokenOperator = address
type tokenOperatorsSet = set (tokenOperator)
type tokenOperators = Map (tokenOwner , tokenOperatorsSet)
type operatorParameter =
record[operator -> tokenOperator , owner -> tokenOwner]
type updateOperatorsAddOrRemove =
sum[Add_operator_p -> operatorParameter ,
Remove_operator_p -> operatorParameter]
type operatorParameterMichelson =
michelson_pair_right_comb (operatorParameter)
type updateOperatorsAddOrRemoveAuxiliary =
sum[Add_operator -> operatorParameterMichelson ,
Remove_operator -> operatorParameterMichelson]
type updateOperatorsAddOrRemoveMichelson =
michelson_or_right_comb (updateOperatorsAddOrRemoveAuxiliary)
type updateOperatorsParameter = list (updateOperatorsAddOrRemoveMichelson)
type tzip12Parameter =
sum[Balance_of -> balanceOfParameterMichelson ,
Permissions_descriptor -> permissionsDescriptorParameter ,
Transfer -> transferParameter ,
U -> unit ,
Update_operators -> updateOperatorsParameter]
type parameter = sum[TZIP12 -> tzip12Parameter]
type entrypointParameter = ( parameter * storage )
type entrypointReturn = ( list (operation) * storage )
const defaultBalance : tokenBalance = +0
const getTokenBalance : ( tokenId * tokenOwner * storage ) -> tokenBalance =
lambda (#P:Some(( tokenId * tokenOwner * storage ))) : None return
let rhs#83 = #P in
let tokenId = rhs#83.0 in
let tokenOwner = rhs#83.1 in
let storage = rhs#83.2 in
let tokensLedger = storage.tzip12.tokensLedger : tokensLedger in
let tokenLookupId = ( tokenOwner , tokenId ) : tokenLookupId in
let tokenBalance =
MAP_FIND_OP(tokenLookupId , tokensLedger) : option (tokenBalance) in
match tokenBalance with
| None -> defaultBalance | Some tokenBalance -> tokenBalance
const updateTokensLedger : ( tokenOwner *
tokenBalance *
transferContents *
storage ) -> storage =
lambda (#P:Some(( tokenOwner * tokenBalance * transferContents * storage ))) : None
return
let rhs#87 = #P in
let transferFrom = rhs#87.0 in
let fromTokenBalance = rhs#87.1 in
let transferContents = rhs#87.2 in
let storage = rhs#87.3 in
let tokenId = transferContents.token_id : tokenId in
let transferTo = transferContents.to_ : tokenOwner in
let transferAmount = transferContents.amount : tokenAmount in
let tokensLedger = storage.tzip12.tokensLedger : tokensLedger in
let tokenLookupIdFrom = ( transferFrom , tokenId ) in
let tokenLookupIdTo = ( transferTo , tokenId ) in
let balanceTo =
(getTokenBalance)@(( tokenId , transferTo , storage )) : tokenBalance in
let tokensLedger =
MAP_UPDATE(tokenLookupIdFrom ,
SOME(ABS(SUB(fromTokenBalance , transferAmount))) ,
tokensLedger) in
let tokensLedger =
MAP_UPDATE(tokenLookupIdTo ,
SOME(ADD(balanceTo , transferAmount)) ,
tokensLedger) in
let storage = { storage with { tokensLedger = tokensLedger } } in storage
type transferContentsIteratorAccumulator = ( storage * tokenOwner )
const transferContentsIterator : ( transferContentsIteratorAccumulator *
transferContentsMichelson ) -> transferContentsIteratorAccumulator =
lambda (#P:Some(( transferContentsIteratorAccumulator *
transferContentsMichelson ))) : None
return
let rhs#98 = #P in
let accumulator = rhs#98.0 in
let transferContentsMichelson = rhs#98.1 in
let rhs#99 = accumulator in
let storage = rhs#99.0 in
let from_ = rhs#99.1 in
let transferContents =
CONVERT_FROM_RIGHT_COMB(transferContentsMichelson) : transferContents in
let tokensLedger = storage.tzip12.tokensLedger : tokensLedger in
let fromTokenBalance =
(getTokenBalance)@(( transferContents.token_id , from_ , storage )) : tokenBalance in
let _ : unit = (canTransfer)@(( from_ , transferContents , storage )) in
match LT(fromTokenBalance , transferContents.amount) with
| true _ ->
FAILWITH(errorInsufficientBalance) : transferContentsIteratorAccumulator
| false _ ->
let storage =
(updateTokensLedger)@(( from_ ,
fromTokenBalance ,
transferContents ,
storage )) in
( storage , from_ )
const transferIterator : ( storage * transferMichelson ) -> storage =
lambda (#P:Some(( storage * transferMichelson ))) : None return
let rhs#104 = #P in
let storage = rhs#104.0 in
let transferMichelson = rhs#104.1 in
let transferAuxiliary =
CONVERT_FROM_RIGHT_COMB(transferMichelson) : transferAuxiliary in
let from_ = transferAuxiliary.from_ : tokenOwner in
let rhs#107 =
LIST_FOLD(transferContentsIterator ,
transferAuxiliary.txs ,
( storage , from_ )) in
let storage = rhs#107.0 in let _ = rhs#107.1 in storage
const transfer : ( transferParameter * storage ) -> entrypointReturn =
lambda (#P:Some(( transferParameter * storage ))) : None return
let rhs#108 = #P in
let transferParameter = rhs#108.0 in
let storage = rhs#108.1 in
let storage = LIST_FOLD(transferIterator , transferParameter , storage) in
( LIST_EMPTY() : list (operation) , storage )
const permissionsDescriptor : ( permissionsDescriptorParameter * storage ) -> entrypointReturn =
lambda (#P:Some(( permissionsDescriptorParameter * storage ))) : None
return
let rhs#110 = #P in
let permissionsDescriptorParameter = rhs#110.0 in
let storage = rhs#110.1 in
let permissionsDescriptorAuxiliary =
record[custom -> match currentPermissionsDescriptor.custom with
| None ->
NONE() : option (customPermissionPolicyMichelson)
| Some custom ->
SOME(CONVERT_TO_RIGHT_COMB(custom)) ,
operator -> CONVERT_TO_RIGHT_COMB(currentPermissionsDescriptor.operator) ,
receiver -> CONVERT_TO_RIGHT_COMB(currentPermissionsDescriptor.receiver) ,
sender -> CONVERT_TO_RIGHT_COMB(currentPermissionsDescriptor.sender)] : permissionsDescriptorAuxiliary in
let currentPermissionsDescriptorMichelson =
CONVERT_TO_RIGHT_COMB(permissionsDescriptorAuxiliary) : permissionsDescriptorMichelson in
let callbackOperation =
CALL(currentPermissionsDescriptorMichelson ,
0mutez ,
permissionsDescriptorParameter) : operation in
( CONS(callbackOperation , LIST_EMPTY()) , storage )
type balanceOfRequest = record[owner -> tokenOwner , token_id -> tokenId]
type balanceOfResponse =
record[balance -> tokenBalance , request -> balanceOfRequest]
type balanceOfCallback = Contract (list (balanceOfResponse))
type balanceOfParameter =
record[callback -> balanceOfCallback , requests -> list (balanceOfRequest)]
type balanceOfRequestMichelson = michelson_pair_right_comb (balanceOfRequest)
type balanceOfResponseAuxiliary =
record[balance -> tokenBalance , request -> balanceOfRequestMichelson]
type balanceOfResponseMichelson =
michelson_pair_right_comb (balanceOfResponseAuxiliary)
type balanceOfCallbackMichelson =
Contract (list (balanceOfResponseMichelson))
type balanceOfParameterAuxiliary =
record[callback -> balanceOfCallbackMichelson ,
requests -> list (balanceOfRequestMichelson)]
type balanceOfParameterMichelson =
michelson_pair_right_comb (balanceOfParameterAuxiliary)
type balanceOfRequestsIteratorAccumulator =
( list (balanceOfResponseMichelson) * storage )
const balanceOfRequestsIterator : ( balanceOfRequestsIteratorAccumulator *
balanceOfRequestMichelson ) -> balanceOfRequestsIteratorAccumulator =
lambda (#P:Some(( balanceOfRequestsIteratorAccumulator *
balanceOfRequestMichelson ))) : None
return
let rhs#114 = #P in
let accumulator = rhs#114.0 in
let balanceOfRequestMichelson = rhs#114.1 in
let rhs#115 : balanceOfRequestsIteratorAccumulator =
accumulator : balanceOfRequestsIteratorAccumulator in
let balanceOfResponses =
rhs#115 : balanceOfRequestsIteratorAccumulator.0 in
let storage = rhs#115 : balanceOfRequestsIteratorAccumulator.1 in
let balanceOfRequest =
CONVERT_FROM_RIGHT_COMB(balanceOfRequestMichelson) : balanceOfRequest in
let tokenBalance =
(getTokenBalance)@(( balanceOfRequest.token_id ,
balanceOfRequest.owner ,
storage )) : tokenBalance in
let balanceOfResponseAuxiliary =
record[balance -> tokenBalance , request -> balanceOfRequestMichelson] : balanceOfResponseAuxiliary in
let balanceOfResponseMichelson =
CONVERT_TO_RIGHT_COMB(balanceOfResponseAuxiliary) : balanceOfResponseMichelson in
let balanceOfResponses =
CONS(balanceOfResponseMichelson , balanceOfResponses) : list (balanceOfResponseMichelson) in
( balanceOfResponses , storage )
const balanceOf : ( balanceOfParameterMichelson * storage ) -> entrypointReturn =
lambda (#P:Some(( balanceOfParameterMichelson * storage ))) : None return
let rhs#121 = #P in
let balanceOfParameterMichelson = rhs#121.0 in
let storage = rhs#121.1 in
let balanceOfParameter =
CONVERT_FROM_RIGHT_COMB(balanceOfParameterMichelson) : balanceOfParameterAuxiliary in
let rhs#123 : balanceOfRequestsIteratorAccumulator =
LIST_FOLD(balanceOfRequestsIterator ,
balanceOfParameter.requests ,
( LIST_EMPTY() : list (balanceOfResponseMichelson) , storage )) : balanceOfRequestsIteratorAccumulator in
let balanceOfResponses =
rhs#123 : balanceOfRequestsIteratorAccumulator.0 in
let _ = rhs#123 : balanceOfRequestsIteratorAccumulator.1 in
let callbackOperation =
CALL(balanceOfResponses , 0mutez , balanceOfParameter.callback) : operation in
( CONS(callbackOperation , LIST_EMPTY()) , storage )
const updateOperators : ( storage *
updateOperatorsAddOrRemoveAuxiliary *
operatorParameterMichelson ) -> storage =
lambda (#P:Some(( storage *
updateOperatorsAddOrRemoveAuxiliary *
operatorParameterMichelson ))) : None
return
let rhs#125 = #P in
let storage = rhs#125.0 in
let updateOperatorsAddOrRemoveAuxiliary = rhs#125.1 in
let operatorParameterMichelson = rhs#125.2 in
let operatorParameter =
CONVERT_FROM_RIGHT_COMB(operatorParameterMichelson) : operatorParameter in
let _ : unit =
(canUpdateOperators)@(( operatorParameter.owner , storage )) in
let tokenOperatorsSet =
MAP_FIND_OP(operatorParameter.owner , storage.tzip12.tokenOperators) : option (tokenOperatorsSet) in
let tokenOperatorsSet =
match updateOperatorsAddOrRemoveAuxiliary with
| Add_operator n ->
match tokenOperatorsSet with
| None ->
SOME(SET_ADD(operatorParameter.operator , SET_EMPTY()))
| Some tokenOperatorsSet ->
SOME(SET_ADD(operatorParameter.operator , tokenOperatorsSet))
| Remove_operator n ->
match tokenOperatorsSet with
| None ->
NONE() : option (tokenOperatorsSet)
| Some tokenOperatorsSet ->
SOME(SET_REMOVE(operatorParameter.operator , tokenOperatorsSet))
: option (tokenOperatorsSet) in
let tokenOperators =
MAP_UPDATE(operatorParameter.owner ,
tokenOperatorsSet ,
storage.tzip12.tokenOperators) : tokenOperators in
{ storage with { tokenOperators = tokenOperators } }
const updateOperatorsIterator : ( storage *
updateOperatorsAddOrRemoveMichelson ) -> storage =
lambda (#P:Some(( storage * updateOperatorsAddOrRemoveMichelson ))) : None
return
let rhs#130 = #P in
let storage = rhs#130.0 in
let updateOperatorsAddOrRemoveMichelson = rhs#130.1 in
let updateOperatorsAddOrRemoveAuxiliary =
CONVERT_FROM_RIGHT_COMB(updateOperatorsAddOrRemoveMichelson) : updateOperatorsAddOrRemoveAuxiliary in
match updateOperatorsAddOrRemoveAuxiliary with
| Add_operator operatorParameterMichelson ->
(updateOperators)@(( storage ,
updateOperatorsAddOrRemoveAuxiliary ,
operatorParameterMichelson ))
| Remove_operator operatorParameterMichelson ->
(updateOperators)@(( storage ,
updateOperatorsAddOrRemoveAuxiliary ,
operatorParameterMichelson ))
const updateOperators : ( updateOperatorsParameter * storage ) -> entrypointReturn =
lambda (#P:Some(( updateOperatorsParameter * storage ))) : None return
let rhs#132 = #P in
let updateOperatorsParameter = rhs#132.0 in
let storage = rhs#132.1 in
let storage =
LIST_FOLD(updateOperatorsIterator , updateOperatorsParameter , storage) in
( LIST_EMPTY() : list (operation) , storage )
const tzip12 =
lambda (#P:Some(( tzip12Parameter * storage ))) : None return
let rhs#134 = #P in
let parameter = rhs#134.0 in
let storage = rhs#134.1 in
match parameter with
| Transfer transferParameter ->
(transfer)@(( transferParameter , storage ))
| Balance_of balanceOfParameterMichelson ->
(balanceOf)@(( balanceOfParameterMichelson , storage ))
| Permissions_descriptor permissionsDescriptorParameter ->
(permissionsDescriptor)@(( permissionsDescriptorParameter , storage ))
| Update_operators updateOperatorsParameter ->
(updateOperators)@(( updateOperatorsParameter , storage ))
| U unit ->
( LIST_EMPTY() : list (operation) , storage )
const main : entrypointParameter -> entrypointReturn =
lambda (#P:Some(entrypointParameter)) : None return
let rhs#135 = #P in
let parameter = rhs#135.0 in
let storage = rhs#135.1 in
match parameter with
| TZIP12 tzip12Parameter -> (tzip12)@(( tzip12Parameter , storage ))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment