-
Notifications
You must be signed in to change notification settings - Fork 2
/
escrow.py
99 lines (83 loc) · 3.86 KB
/
escrow.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
import smartpy as sp
class Escrow(sp.Contract):
def __init__(self):
self.init(m = sp.big_map({}, tkey=sp.TAddress, tvalue=sp.TMutez))
def verify_pending_transaction(self, sender):
sp.verify(self.data.m.contains(sender), message = "no pending transaction")
@sp.entry_point
def add_funds(self):
sp.verify(sp.amount > sp.tez(0))
sp.verify(~self.data.m.contains(sp.sender), message = "pending transaction")
self.data.m[sp.sender] = sp.amount
@sp.entry_point
def pull_funds(self):
self.verify_pending_transaction(sp.sender)
sp.send(sp.sender, self.data.m[sp.sender])
del self.data.m[sp.sender]
class Marketplace(Escrow):
def __init__(self, fa2, admin):
Escrow.__init__(self)
self.update_initial_storage(fa2 = fa2, administrator = admin)
def fa2_transfer(self, fa2, from_, to_, ids):
txs_type = sp.TRecord(amount=sp.TNat, to_=sp.TAddress, token_id=sp.TNat).layout(("to_", ("token_id", "amount")))
c = sp.contract(sp.TList(sp.TRecord(from_=sp.TAddress, txs=sp.TList(txs_type))), fa2, entry_point='transfer').open_some()
txs = sp.local('txs', sp.list(t=txs_type))
sp.for id in ids:
txs.value.push(sp.record(amount=1, to_=to_, token_id=id))
sp.transfer(sp.list([sp.record(from_=from_, txs=txs.value)]), sp.mutez(0), c)
@sp.entry_point
def redeem_funds(self, params):
sp.set_type(params.to, sp.TAddress)
sp.set_type(params.ids, sp.TList(sp.TNat))
sp.set_type(params.amount, sp.TMutez)
sp.verify(sp.sender == self.data.administrator)
self.verify_pending_transaction(params.to)
amount = sp.local('amount', self.data.m[params.to])
sp.verify(amount.value == params.amount, message = "amount mismatch")
sp.send(self.data.administrator, amount.value)
self.fa2_transfer(self.data.fa2, sp.sender, params.to, params.ids)
del self.data.m[params.to]
class FA2(sp.Contract):
def __init__(self):
self.init()
@sp.entry_point
def transfer(self, params):
sp.set_type(params, sp.TList(sp.TRecord(from_=sp.TAddress, txs=sp.TList(sp.TRecord(amount=sp.TNat, to_=sp.TAddress, token_id=sp.TNat).layout(("to_", ("token_id", "amount"))))).layout(("from_", "txs"))))
pass
@sp.add_test(name = "Marketplace")
def test():
s = sp.test_scenario()
s.h1("Escrow")
c = Escrow()
s += c
admin = sp.test_account("Administrator")
alice = sp.test_account("Alice")
bob = sp.test_account("Robert")
s.show([admin, alice, bob])
c.add_funds().run(sender = alice, valid = False)
c.add_funds().run(sender = alice, amount = sp.tez(5))
c.add_funds().run(sender = alice, amount = sp.tez(1), valid = False)
c.pull_funds().run(sender = bob, valid = False)
c.pull_funds().run(sender = alice)
s.verify(c.balance == sp.tez(0))
fa2 = FA2()
s += fa2
s.h1("Marketplace")
c = Marketplace(fa2.address, admin.address)
s += c
ids = [1, 2, 3]
c.add_funds().run(sender = alice, amount = sp.tez(1))
c.redeem_funds(ids = ids, to = alice.address, amount = sp.tez(1)).run(sender = alice, valid = False)
c.redeem_funds(ids = ids, to = bob.address, amount = sp.tez(1)).run(sender = admin, valid = False)
c.redeem_funds(ids = ids, to = alice.address, amount = sp.tez(0)).run(sender = admin, valid = False)
c.redeem_funds(ids = ids, to = alice.address, amount = sp.tez(5)).run(sender = admin, valid = False)
c.redeem_funds(ids = ids, to = alice.address, amount = sp.tez(1)).run(sender = admin)
s.verify(c.balance == sp.tez(0))
@sp.add_test(name = "Deploy")
def deploy():
s = sp.test_scenario()
s.h1("Deploy")
fa2Contract = sp.address("KT1N1a7TA1rEedQo2pEQXhuVgSQNvgRWKkdJ")
adminAddress = sp.address("tz1Qej2aPmeZECBZHV5meTLC1X6DWRhSCoY4")
c = Marketplace(fa2Contract, adminAddress)
s += c