-
Notifications
You must be signed in to change notification settings - Fork 3
Expand file tree
/
Copy pathCFA2.py
More file actions
96 lines (85 loc) · 3.98 KB
/
Copy pathCFA2.py
File metadata and controls
96 lines (85 loc) · 3.98 KB
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
import smartpy as sp
CTErrors = sp.io.import_script_from_url(
"file:contracts/errors/CTokenErrors.py")
EC = CTErrors.ErrorCodes
CToken = sp.io.import_script_from_url("file:contracts/CToken.py")
TSetCashParams = sp.TList(
sp.TRecord(
balance=sp.TNat,
request=sp.TRecord(
owner=sp.TAddress,
token_id=sp.TNat
).layout(("owner", "token_id"))
).layout(("request", "balance"))
)
TBalanceOfParams = sp.TRecord(
callback=sp.TContract(TSetCashParams),
requests=sp.TList(
sp.TRecord(
owner=sp.TAddress,
token_id=sp.TNat
).layout(("owner", "token_id"))
)
).layout(("requests", "callback"))
class CFA2(CToken.CToken):
def __init__(self, comptroller_, interestRateModel_, initialExchangeRateMantissa_, administrator_, metadata_, token_metadata_, fa2_TokenAddress_, tokenId_, **extra_storage):
CToken.CToken.__init__(self,
comptroller_,
interestRateModel_,
initialExchangeRateMantissa_,
administrator_,
metadata_,
token_metadata_,
fa2_TokenAddress=fa2_TokenAddress_,
tokenId=tokenId_,
currentCash=sp.nat(0),
**extra_storage)
def getCashImpl(self):
return self.data.currentCash
def updateCash(self):
cashSum = sp.compute(self.data.currentCash +
self.data.totalSupply + self.data.totalReserves)
# prevent transaction failing if CToken is not listed in underlying fa2 yet
with sp.if_(cashSum > 0):
self.activateOp(CToken.OP.CTokenOperations.GET_CASH)
handle = sp.contract(
TBalanceOfParams, self.data.fa2_TokenAddress, "balance_of").open_some()
data = sp.record(
callback=sp.self_entry_point("setCash"),
requests=sp.list([
sp.record(owner=sp.self_address,
token_id=self.data.tokenId)
])
)
sp.transfer(data, sp.mutez(0), handle)
@sp.entry_point(lazify=True)
def setCash(self, params):
sp.set_type(params, TSetCashParams)
self.verifyAndFinishActiveOp(CToken.OP.CTokenOperations.GET_CASH)
sp.verify(sp.sender == self.data.fa2_TokenAddress,
EC.CT_INVALID_CASH_SENDER)
sp.verify(sp.len(params) == 1, EC.CT_INVALID_CASH_DATA)
sp.for cash in params:
sp.verify(cash.request.token_id ==
self.data.tokenId, EC.CT_INVALID_CASH_DATA)
sp.verify(cash.request.owner == sp.self_address,
EC.CT_INVALID_CASH_DATA)
self.data.currentCash = cash.balance
def doTransferIn(self, from_, amount):
# Listed FA2 underlyings must credit exactly ``amount`` on every
# successful transfer. Fee-on-transfer and transfer-time-rebasing
# tokens are unsupported because currentCash is updated by amount.
self.transferFA2(from_, sp.self_address, amount,
self.data.fa2_TokenAddress, self.data.tokenId)
# Keep the accounting cache in lockstep with the scheduled token
# transfer. Subsequent operations in the same operation group use this
# value to price shares and check liquidity.
self.data.currentCash += amount
def doTransferOut(self, to_, amount, isContract=False):
self.data.currentCash = self.sub_nat_nat(self.data.currentCash, amount)
self.transferFA2(sp.self_address, to_, amount,
self.data.fa2_TokenAddress, self.data.tokenId)
def verifySweepFA2(self, tokenAddress, id):
isNotUnderlying = (tokenAddress != self.data.fa2_TokenAddress) | (
id != self.data.tokenId)
sp.verify(isNotUnderlying, EC.CT_SWEEP_UNDERLYING)