2020-06-05 12:51:37 +02:00
|
|
|
type tokens = (address, nat) big_map
|
|
|
|
|
|
|
|
type allowances = (address * address, nat) big_map
|
|
|
|
|
|
|
|
type storage =
|
|
|
|
{tokens : tokens;
|
|
|
|
allowances : allowances;
|
|
|
|
total_amount : nat}
|
|
|
|
|
|
|
|
type transfer =
|
|
|
|
{address_from : address;
|
|
|
|
address_to : address;
|
|
|
|
value : nat}
|
|
|
|
|
|
|
|
type approve = {spender : address; value : nat}
|
|
|
|
|
|
|
|
type getAllowance =
|
|
|
|
{owner : address;
|
|
|
|
spender : address;
|
|
|
|
callback : nat contract}
|
|
|
|
|
|
|
|
type getBalance = {owner : address; callback : nat contract}
|
|
|
|
|
|
|
|
type getTotalSupply = {callback : nat contract}
|
|
|
|
|
|
|
|
type action =
|
2020-06-08 13:27:24 +02:00
|
|
|
Transfer of transfer
|
|
|
|
| Approve of approve
|
|
|
|
| GetAllowance of getAllowance
|
|
|
|
| GetBalance of getBalance
|
|
|
|
| GetTotalSupply of getTotalSupply
|
2020-06-05 12:51:37 +02:00
|
|
|
|
|
|
|
let transfer (p, s : transfer * storage)
|
|
|
|
: operation list * storage =
|
|
|
|
let new_allowances =
|
|
|
|
if Tezos.sender = p.address_from
|
|
|
|
then s.allowances
|
|
|
|
else
|
|
|
|
let authorized_value =
|
|
|
|
match Big_map.find_opt
|
|
|
|
(Tezos.sender, p.address_from)
|
|
|
|
s.allowances
|
|
|
|
with
|
|
|
|
Some value -> value
|
|
|
|
| None -> 0n
|
|
|
|
in if (authorized_value < p.value)
|
|
|
|
then (failwith "Not Enough Allowance" : allowances)
|
|
|
|
else
|
|
|
|
Big_map.update
|
|
|
|
(Tezos.sender, p.address_from)
|
|
|
|
(Some (abs (authorized_value - p.value)))
|
|
|
|
s.allowances
|
|
|
|
in let sender_balance =
|
|
|
|
match Big_map.find_opt p.address_from s.tokens with
|
|
|
|
Some value -> value
|
|
|
|
| None -> 0n
|
|
|
|
in if (sender_balance < p.value)
|
|
|
|
then
|
|
|
|
(failwith "Not Enough Balance"
|
|
|
|
: operation list * storage)
|
|
|
|
else
|
|
|
|
let new_tokens =
|
|
|
|
Big_map.update
|
|
|
|
p.address_from
|
|
|
|
(Some (abs (sender_balance - p.value)))
|
|
|
|
s.tokens
|
|
|
|
in let receiver_balance =
|
|
|
|
match Big_map.find_opt p.address_to s.tokens
|
|
|
|
with
|
|
|
|
Some value -> value
|
|
|
|
| None -> 0n
|
|
|
|
in let new_tokens =
|
|
|
|
Big_map.update
|
|
|
|
p.address_to
|
|
|
|
(Some (receiver_balance + p.value))
|
|
|
|
new_tokens
|
|
|
|
in ([] : operation list),
|
|
|
|
{s with
|
|
|
|
tokens = new_tokens;
|
|
|
|
allowances = new_allowances}
|
|
|
|
|
|
|
|
let approve (p, s : approve * storage)
|
|
|
|
: operation list * storage =
|
|
|
|
let previous_value =
|
|
|
|
match Big_map.find_opt
|
|
|
|
(p.spender, Tezos.sender)
|
|
|
|
s.allowances
|
|
|
|
with
|
|
|
|
Some value -> value
|
|
|
|
| None -> 0n
|
|
|
|
in if previous_value > 0n && p.value > 0n
|
|
|
|
then
|
|
|
|
(failwith "Unsafe Allowance Change"
|
|
|
|
: operation list * storage)
|
|
|
|
else
|
|
|
|
let new_allowances =
|
|
|
|
Big_map.update
|
|
|
|
(p.spender, Tezos.sender)
|
|
|
|
(Some (p.value))
|
|
|
|
s.allowances
|
|
|
|
in ([] : operation list),
|
|
|
|
{s with
|
|
|
|
allowances = new_allowances}
|
|
|
|
|
|
|
|
let getAllowance (p, s : getAllowance * storage)
|
|
|
|
: operation list * storage =
|
|
|
|
let value =
|
|
|
|
match Big_map.find_opt (p.owner, p.spender) s.allowances
|
|
|
|
with
|
|
|
|
Some value -> value
|
|
|
|
| None -> 0n
|
|
|
|
in let op = Tezos.transaction value 0mutez p.callback
|
|
|
|
in ([op], s)
|
|
|
|
|
|
|
|
let getBalance (p, s : getBalance * storage)
|
|
|
|
: operation list * storage =
|
|
|
|
let value =
|
|
|
|
match Big_map.find_opt p.owner s.tokens with
|
|
|
|
Some value -> value
|
|
|
|
| None -> 0n
|
|
|
|
in let op = Tezos.transaction value 0mutez p.callback
|
|
|
|
in ([op], s)
|
|
|
|
|
|
|
|
let getTotalSupply (p, s : getTotalSupply * storage)
|
|
|
|
: operation list * storage =
|
|
|
|
let total = s.total_amount
|
|
|
|
in let op = Tezos.transaction total 0mutez p.callback
|
|
|
|
in ([op], s)
|
|
|
|
|
|
|
|
let main (a, s : action * storage) =
|
|
|
|
match a with
|
|
|
|
Transfer p -> transfer (p, s)
|
|
|
|
| Approve p -> approve (p, s)
|
|
|
|
| GetAllowance p -> getAllowance (p, s)
|
|
|
|
| GetBalance p -> getBalance (p, s)
|
|
|
|
| GetTotalSupply p -> getTotalSupply (p, s)
|