def TokenToTezSwap(self, params): tokensIn = sp.local("tokensIn", params.tokensIn).value minTezOut = sp.local("minTokensOut", params.minTezOut).value self.TokenToTez(buyer=sp.sender, recipient=sp.sender, tokensIn=tokensIn, minTezOut=minTezOut)
def TezToToken(self, recipient: sp.TAddress, tezIn: sp.TNat, minTokensOut: sp.TNat): this = self.data.address sp.verify(tezIn > sp.mutez(0), message="Wrong tezIn") sp.verify(minTokensOut > 0, message="Wrong minTokensOut") fee = sp.fst(sp.ediv(tezIn, self.data.feeRate).open_some()) # TODO: ???? newTezPool = sp.local("newTezPool", self.data.tezPool).value + tezIn tempTezPool = abs(newTezPool - fee) newTokenPool = sp.fst(sp.ediv(sp.local( "newTokenPool", self.data.invariant).value, tempTezPool).open_some()) tokensOut = abs( sp.local("tokensOut", self.data.tokenPool).value - newTokenPool) sp.verify(tokensOut >= minTokensOut, message="Wrong minTokensOut") sp.verify(tokensOut <= self.data.tokenPool, message="Wrong tokenPool") self.data.tezPool = newTezPool self.data.tokenPool = newTokenPool self.data.invariant = sp.split_tokens(newTezPool, newTokenPool, sp.nat(1)) token_contract = sp.contract( sp.TRecord(account_from=sp.TAddress, destination=sp.TAddress, value=sp.TNat), address=self.data.tokenAddress, entry_point="Transfer" ).open_some() sp.transfer(sp.record(account_from=this, destination=recipient, value=tokensOut), sp.mutez(0), token_contract)
def OracleExerciseSecurity(self,params): sp.set_type(params, sp.TRecord(price = sp.TNat, owner = sp.TAddress)) sp.verify(sp.sender == self.data.oracle) sp.verify(sp.now <= self.data.Securities[params.owner].expiry) sp.verify(self.data.Securities[params.owner].strikePrice > params.price) self.data.adminAccount += self.data.Securities[params.owner].adminpayment Amount = sp.local('Amount',abs(self.data.Securities[params.owner].strikePrice - params.price)*10000000) Amount.value = Amount.value*self.data.Securities[params.owner].options CalAmount = sp.local('CalAmount',sp.nat(0)) PoolAmount = sp.local('PoolAmount',self.data.Securities[params.owner].strikePrice*self.data.Securities[params.owner].options*10000000) PoolAmount.value = abs(PoolAmount.value - self.data.Securities[params.owner].adminpayment) sp.for i in self.data.Securities[params.owner].pool.keys(): CalAmount.value += (self.data.Securities[params.owner].pool[i]*Amount.value)/(PoolAmount.value) self.data.LiquidityProvider[i].locked = abs(self.data.LiquidityProvider[i].locked - self.data.Securities[params.owner].pool[i]) self.data.Securities[params.owner].pool[i] = abs(self.data.Securities[params.owner].pool[i] - (self.data.Securities[params.owner].pool[i]*Amount.value)/(PoolAmount.value) ) sp.if self.data.poolSet.contains(i): self.data.LiquidityProvider[i].amount += self.data.Securities[params.owner].pool[i] self.data.totalSupply += self.data.Securities[params.owner].pool[i]
def swap(i): tempBid = sp.local("tempBid", self.data.bids[nat(i)]) tempAgent = sp.local("tempAgent", self.data.agents[nat(i)]) self.data.bids[nat(i)] = self.data.bids[nat(i - 1)] self.data.agents[nat(i)] = self.data.agents[nat(i - 1)] self.data.bids[nat(i - 1)] = tempBid.value self.data.agents[nat(i - 1)] = tempAgent.value
def createInstance(self, params): asset_id = sp.local('asset_id', params.asset_id) asset_name = sp.local('asset_name', params.asset_name) sp.if asset_id.value == 0: asset_id.value = self.data.counter self.data.counter = self.data.counter + 1
def TokenToTezPayment(self, params): recipient = sp.local("recipient", params.recipient).value tokensIn = sp.local("tokensIn", params.tokensIn).value minTezOut = sp.local("minTokensOut", params.minTezOut).value self.TokenToTez(buyer=sp.sender, recipient=recipient, tokensIn=tokensIn, minTezOut=minTezOut)
def TokenToTokenIn(self, params): recipient = sp.local("recipient", params.recipient).value minTokensOut = sp.local("minTokensOut", params.minTokensOut).value sp.verify(sp.sender == self.data.factoryAddress, message="Wrong minTezOut") return self.TezToToken(recipient=recipient, tezIn=sp.amount, minTokensOut=minTokensOut)
def buyTicket(self, qty): sp.verify(sp.tez(qty) == sp.amount) change = sp.local('change', sp.tez(0)) canBuy = sp.local('canBuy', qty) remaining = sp.as_nat(self.data.limit - self.data.id) sp.if qty > remaining: canBuy.value = remaining change.value = sp.tez(sp.as_nat(qty - remaining))
def TokenToTokenSwap(self, params): tokensIn = sp.local("tokensIn", params.tokensIn).value minTokensOut = sp.local("minTokensOut", params.minTokensOut).value tokenOutAddress = sp.local( "tokenOutAddress", params.tokenOutAddress).value self.TokenToTokenOut( buyer=sp.sender, recipient=sp.sender, tokensIn=tokensIn, minTokensOut=minTokensOut, tokenOutAddress=tokenOutAddress)
def cancel_request(self, client_request_id): # We do not want to check active here (it would be bad for the client). # sp.sender needs to be validated; this process is done through the use of the reverse_request_key. reverse_request_key = sp.compute(sp.record(client = sp.sender, client_request_id = client_request_id)) request_id = sp.local('request_id', self.data.reverse_requests[reverse_request_key]).value request = sp.local('request', self.data.requests[request_id]).value sp.verify(request.timeout <= sp.now, message = "TTL not met") token = sp.contract(self.token_contract.batch_transfer.get_type(), self.data.token, entry_point = "transfer").open_some(message = "Incompatible token interface") sp.transfer([sp.record(from_ = sp.to_address(sp.self), txs = [sp.record(to_ = request.client, token_id = 0, amount = request.amount)])], sp.tez(0), token) del self.data.requests[request_id] del self.data.reverse_requests[reverse_request_key]
def OrOputBuyer(self,params): # Verify Oracle Address sp.verify(sp.sender == self.data.Oracle) sp.verify(sp.now < self.data.validation.cycleEnd) sp.verify(~ self.data.contractBuyer.contains(params.address)) self.data.model[80] = {7:1,14:2,21:4} self.data.model[90] = {7:2,14:4,21:8} self.data.model[100] = {7:4,14:8,21:16} self.data.model[110] = {7:2,14:4,21:8} self.data.model[120] = {7:1,14:2,21:4} sp.verify(self.data.model.contains(params.Ratio)) sp.verify(self.data.model[params.Ratio].contains(params.expire)) TotalAmount = sp.local('TotalAmount',params.StrikePrice*params.Options*100) Interest = sp.local('Interest',self.data.model[params.Ratio][params.expire]) del self.data.model[80] del self.data.model[90] del self.data.model[100] del self.data.model[110] del self.data.model[120] Deadline = sp.now.add_days(params.expire) sp.verify(self.data.validation.totalSupply > TotalAmount.value) sp.verify(self.data.validation.cycleEnd > sp.now.add_days(params.expire)) self.data.adminAccount += params.StrikePrice*params.Options self.data.buyerSet.add(sp.sender) CollateralTotal = sp.local('CollateralTotal',0) PremiumCal = sp.local('PremiumCal',params.StrikePrice*params.Options*Interest.value) Payment = sp.local('Payment',params.StrikePrice*params.Options*Interest.value + params.StrikePrice*params.Options) sp.if params.StrikePrice > params.xtzPrice: PremiumCal.value += abs((params.StrikePrice - params.xtzPrice)*100) Payment.value += abs((params.StrikePrice - params.xtzPrice)*100)
def sellShort(self, params): sp.set_type(params, sp.TRecord(quantity = sp.TNat, price_buy = sp.TNat, price_sell = sp.TNat)) sp.verify(~self.data.result.is_some()) sp.verify(self.data.sharesShort[sp.sender][params.price_buy] >= sp.to_int(params.quantity)) sp.verify(params.price_sell <= 1000000) matchPrice = 1000000 - params.price_sell confirmed = sp.local('confirmed', False) index = sp.local('index', -1) sp.for i in self.data.sellLongOrders.keys(): order = self.data.orders[i] sp.if ~confirmed.value & (order.price == sp.as_nat(matchPrice)) & (order.quantity == params.quantity) & ~(order.creator == sp.sender): confirmed.value = True index.value = i
def TokenToTokenOut(self, buyer: sp.TAddress, recipient: sp.TAddress, tokensIn: sp.TNat, minTokensOut: sp.TNat, tokenOutAddress: sp.TAddress): this = self.data.address sp.verify(tokensIn > 0, message="Wrong tokensIn") sp.verify(minTokensOut > 0, message="Wrong minTokensOut") fee = tokensIn / self.data.feeRate # TODO: ???? newTokenPool = sp.local( "newTokenPool", self.data.tokenPool).value + tokensIn tempTokenPool = abs(newTokenPool - fee) newTezPool = sp.fst(sp.ediv(sp.local( "newTezPool", self.data.invariant).value, tempTokenPool).open_some()) tezOut = abs(sp.local("tezOut", self.data.tezPool).value - newTezPool) sp.verify(sp.mutez(tezOut) <= self.data.tezPool, message="Wrong tezPool") self.data.tezPool = newTezPool self.data.tokenPool = newTokenPool self.data.invariant = sp.mutez(newTezPool * newTokenPool) token_contract = sp.contract( sp.TRecord(account_from=sp.TAddress, destination=sp.TAddress, value=sp.TNat), address=self.data.tokenAddress, entry_point="Transfer" ).open_some() factory_contract = sp.contract( sp.TRecord(tokenOutAddress=sp.TAddress, recipient=sp.TAddress, minTokensOut=sp.TNat), address=self.data.factoryAddress, entry_point="TokenToExchangeLookup" ).open_some() sp.transfer(sp.record(account_from=buyer, destination=this, value=tokensIn), sp.mutez(0), token_contract) sp.transfer(sp.record(tokenOutAddress=tokenOutAddress, destination=recipient, value=minTokensOut), sp.mutez(tezOut), factory_contract)
def deposit(self, params): sp.verify(sp.amount > sp.mutez(0), message = "Deposit too low") sp.verify(sp.sender != self.data.issuer, message = "Invalid address") period = self.getPeriod() tokenBalance = sp.local('tokenBalance', 0) requiredCollateral = sp.local('requiredCollateral', sp.tez(0)) expectedReturn = sp.ediv(sp.amount, self.data.schedule[period]) coins = sp.ediv(sp.amount, sp.tez(1)) sp.if (expectedReturn.is_some()) & (coins.is_some()): tokenBalance.value = sp.fst(expectedReturn.open_some()) wholeCoins = sp.fst(coins.open_some()) sp.verify(tokenBalance.value > wholeCoins, message = "Deposit too low") requiredCollateral.value = sp.tez(sp.as_nat(tokenBalance.value - wholeCoins))
def buyLong(self, params): sp.set_type(params, sp.TRecord(quantity = sp.TNat, price = sp.TNat)) sp.verify(~self.data.result.is_some()) self.verifyPrice(params, sp.amount) matchPrice = 1000000 - params.price confirmed = sp.local('confirmed', False) index = sp.local('index', -1) sp.for i in self.data.buyShortOrders.keys(): order = self.data.orders[i] sp.if ~confirmed.value & (order.price == sp.as_nat(matchPrice)) & (order.quantity == params.quantity) & ~(order.creator == sp.sender): confirmed.value = True index.value = i self.addShares(sp.record(sender = sp.sender, position = Position.Long, price = params.price, quantity = params.quantity)) self.addShares(sp.record(sender = order.creator, position = Position.Short, price = sp.as_nat(matchPrice), quantity = order.quantity))
def hasWon(self,cycle,range): betsByCycle = self.data.bettors[sp.sender] betAmount = sp.local("betAmount",sp.mutez(0)) betAmount = betsByCycle[cycle].amount totalRewards = sp.local("totalRewards",sp.mutez(0)) totalRewards = sp.split_tokens(self.data.cycleData[cycle].totalAmount , sp.as_nat(sp.fst(self.data.cycleData[cycle].roi)) , sp.as_nat(sp.snd(self.data.cycleData[cycle].roi))) totalRewards = sp.split_tokens(totalRewards , sp.nat(98) , sp.nat(100)) reward = sp.split_tokens(totalRewards , sp.fst(sp.ediv(betAmount , sp.mutez(1)).open_some()) , sp.fst(sp.ediv(self.data.cycleData[cycle].amountByRange[range],sp.mutez(1)).open_some()) ) betsByCycle[cycle].withdrawn=True betsByCycle[cycle].withdrawnAmount = betsByCycle[cycle].amount + reward sp.send(sp.sender , betsByCycle[cycle].amount + reward)
def transfer(self, params): sp.set_type( params, sp.TRecord(from_=sp.TAddress, to_=sp.TAddress, value=sp.TNat)).layout( ("from_ as from", ("to_ as to", "value"))) sender = sp.local("sender", sp.sender) with sp.if_((self.transfer_presigned(params))): # Setting sender.value to from_ so call to transfer_helper will be authorized sender.value = params.from_ sp.verify((sender.value == self.data.administrator) | ( ~self.data.paused & ( (params.from_ == sender.value) | (self.data.balances[ params.from_].approvals[sender.value] >= params.value)))) self.addAddressIfNecessary(params.to_) sp.verify(self.data.balances[params.from_].balance >= params.value) self.data.balances[params.from_].balance = sp.as_nat( self.data.balances[params.from_].balance - params.value) self.data.balances[params.to_].balance += params.value with sp.if_(((params.from_ != sender.value) & (self.data.administrator != sender.value))): self.data.balances[params.from_].approvals[ sender.value] = sp.as_nat( self.data.balances[params.from_].approvals[sender.value] - params.value)
def InvestLiquidity(self, params): minShares = params.minShares candidate = params.candidate sp.verify(sp.amount > sp.mutez(0), message="Wrong amount") sp.verify(minShares > sp.nat(0), message="Wrong tokenAmount") tezPerShare = sp.split_tokens(self.data.tezPool, sp.nat(1), self.data.totalShares) sp.verify(sp.amount >= tezPerShare, message="Wrong tezPerShare") sharesPurchased = sp.fst(sp.ediv(sp.amount, tezPerShare).open_some()) sp.verify(sharesPurchased >= minShares, message="Wrong sharesPurchased") tokensPerShare = self.data.tokenPool / self.data.totalShares tokensRequired = sharesPurchased * tokensPerShare share = sp.local("share", self.data.shares.get(sp.sender, 0)).value self.data.shares[sp.sender] = share + sharesPurchased self.data.tezPool += sp.amount self.data.tokenPool += tokensRequired self.data.invariant = sp.split_tokens(self.data.tezPool, self.data.tokenPool, sp.nat(1)) self.data.totalShares += sharesPurchased sp.if self.data.candidates.contains(sp.sender): prevVotes = self.data.votes.get(self.data.candidates[sp.sender], 0) self.data.votes[self.data.candidates[sp.sender]] = abs( prevVotes - share)
def accept_bid_for_bot(self, params): # Make sure that sp.sender has admin access otherwise don't proceed forward # Make sure that contract isn't paused sp.set_type(params.token_id, sp.TNat) sp.set_type(params.nft_amount, sp.TNat) # Make sure that the NFT token id is already present in the ledger sp.verify(self.token_id_set.contains(self.data.all_tokens, params.token_id), "TOKEN ID NOT FOUND") # NFT transfer amount should be 1 sp.verify(params.nft_amount == 1, "NFT AMOUNT OF 1 REQUIRED") # Make sure that the caller is the owner of NFT token id else throw error user = self.ledger_key.make(sp.sender, params.token_id) sp.verify(self.data.ledger.contains(user) == True, "NOT OWNER OF NFT TOKEN ID") # Make sure their is aleast one bid for NFT token id sp.verify(sp.len(self.data.bid[params.token_id]) > 0, "NO BIDDER YET") highest_bidder = sp.local("highest_bidder", sp.record( has_bid = False, bidder = sp.address("tz1iLVzBpCNTGz6tCBK2KHaQ8o44mmhLTBio"), bid_value = sp.mutez(0) )) # transfer the highest bidder value to the seller account sp.for bidder in self.data.bid[params.token_id]: # store highest bidder sp.if bidder.bid_value > highest_bidder.value.bid_value: highest_bidder.value = bidder
def claimFor(self, beneficiery): sp.verify(self.data.schedules.contains(beneficiery)) sp.for schedule_name in self.data.schedules[beneficiery].keys(): schedule = self.data.schedules[beneficiery][schedule_name] vested_amount = self._vested( sp.record( beneficiery= beneficiery, schedule_name= schedule_name ) ) claim_amount = sp.local('claim_amount', sp.as_nat(0)) claim_amount.value = sp.as_nat(vested_amount - schedule.claimed_amount) schedule.claimed_amount += claim_amount.value self._transfer( sp.record( from_ = sp.self_address, to_ = beneficiery, amount = claim_amount.value, token_id = schedule.token_id, token_address = schedule.token_address ) )
def transfer_presigned(self, params): sp.set_type( params, sp.TRecord(from_=sp.TAddress, to_=sp.TAddress, value=sp.TNat)) params_hash = sp.blake2b(sp.pack(params)) #unsigned = sp.blake2b(mi.operator("SELF; ADDRESS; CHAIN_ID; PAIR; PAIR; PACK", [sp.TPair(sp.TNat, sp.TBytes)], [sp.TBytes])(sp.pair(self.data.counter, params_hash))) permit_key = sp.pair(params.from_, params_hash) effective_expiry = sp.local("effective_expiry", 0) with sp.if_(self.data.permits.contains(permit_key)): permit_submission_timestamp = self.data.permits[permit_key] with sp.if_( self.data.permit_expiries.contains(permit_key) & self.data.permit_expiries[permit_key].is_some()): effective_expiry.value = self.data.permit_expiries[ permit_key].open_some() with sp.else_(): with sp.if_( self.data.user_expiries.contains(params.from_) & self.data.user_expiries[params.from_].is_some()): effective_expiry.value = self.data.user_expiries[ params.from_].open_some() with sp.else_(): effective_expiry.value = self.data.default_expiry # Deleting permit regardless of whether or not its expired with sp.if_( sp.as_nat(sp.now - permit_submission_timestamp) >= effective_expiry.value): # Expired self.delete_permit(permit_key) sp.result(sp.bool(False)) with sp.else_(): self.delete_permit(permit_key) sp.result(sp.bool(True)) with sp.else_(): sp.result(sp.bool(False))
def transfer(self, params): sp.set_type(params, sp.TRecord(from_=sp.TAddress, to_=sp.TAddress, value=sp.TNat)).layout(("from_ as from", ("to_ as to", "value"))) sender = sp.local("sender", sp.sender) sp.if (self.transfer_presigned(params)): # Setting sender.value to from_ so call to transfer_helper will be authorized sender.value = params.from_
def remove_execution_request(self, removal_request): sp.set_type(removal_request, RemovalRequest.get_type()) signing_payload = RemovalRequest.get_signing_payload(sp.chain_id, sp.self_address, removal_request.timelock_id) valid_signatures_counter = sp.local('valid_signatures_counter', sp.nat(0)) sp.for operator_public_key in self.data.operator_public_keys: sp.if sp.check_signature(operator_public_key, removal_request.signatures[sp.hash_key(operator_public_key)], sp.pack(signing_payload)): valid_signatures_counter.value += 1
def add_execution_request(self, execution_request): sp.set_type(execution_request, ExecutionRequest.get_type()) signing_payload = ExecutionRequest.get_signing_payload(sp.chain_id, sp.self_address, self.data.nonce+sp.nat(1), execution_request.execution_payload) valid_signatures_counter = sp.local('valid_signatures_counter', sp.nat(0)) sp.for operator_public_key in self.data.operator_public_keys: sp.if sp.check_signature(operator_public_key, execution_request.signatures[sp.hash_key(operator_public_key)], sp.pack(signing_payload)): valid_signatures_counter.value += 1
def putBuyer(self,params): sp.verify(sp.now < self.data.validation.cycleEnd) sp.verify(~ self.data.contractBuyer.contains(sp.sender)) self.data.model[self.data.xtzPrice*90] = {7:1,14:2,21:4} self.data.model[self.data.xtzPrice*95] = {7:2,14:4,21:8} self.data.model[self.data.xtzPrice*100] = {7:4,14:8,21:16} self.data.model[self.data.xtzPrice*105] = {7:2,14:4,21:8} self.data.model[self.data.xtzPrice*110] = {7:1,14:2,21:4} sp.verify(self.data.model.contains(params.StrikePrice*100)) sp.verify(self.data.model[params.StrikePrice*100].contains(params.expire)) TotalAmount = sp.local('TotalAmount',params.StrikePrice*params.Options*100) Interest = sp.local('Interest',self.data.model[params.StrikePrice*100][params.expire]) Deadline = sp.now.add_days(params.expire) sp.verify(self.data.validation.totalSupply > TotalAmount.value) sp.verify(self.data.validation.cycleEnd > sp.now.add_days(params.expire)) # Deleting Pricing Model del self.data.model[self.data.xtzPrice*90] del self.data.model[self.data.xtzPrice*95] del self.data.model[self.data.xtzPrice*100] del self.data.model[self.data.xtzPrice*105] del self.data.model[self.data.xtzPrice*110] self.data.adminAccount += params.StrikePrice*params.Options self.data.buyerSet.add(sp.sender) CollateralTotal = sp.local('CollateralTotal',0) PremiumCal = sp.local('PremiumCal',params.StrikePrice*params.Options*Interest.value) Payment = sp.local('Payment',params.StrikePrice*params.Options*Interest.value + params.StrikePrice*params.Options) self.Lock(sp.sender,Payment.value) sp.if params.StrikePrice > self.data.xtzPrice: PremiumCal.value += abs((params.StrikePrice - self.data.xtzPrice)*100)
def balance_of(self, balance_of_request): """As per FA2 standard, takes balance_of requests and reponds on the provided callback contract""" sp.set_type(balance_of_request, BalanceOf.get_type()) responses = sp.local("responses", sp.set_type_expr(sp.list([]),BalanceOf.get_response_type())) sp.for request in balance_of_request.requests: sp.verify(self.data.token_metadata.contains(request.token_id), message = FA2ErrorMessage.TOKEN_UNDEFINED) responses.value.push(sp.record(request = request, balance = self.data.ledger.get(LedgerKey.make(request.owner, request.token_id),0)))
def closeAuction(self, param): sp.if ( sp.len(self.data.bids) > 0 ) : lenCtr = sp.local("lenctr", sp.len(self.data.ctrs)) self.data.ctrs[lenCtr.value] = 0 i = sp.local('i', 0) jc = sp.local('jc', 0) price_i = sp.local("price_i", 0) oneNat = sp.as_nat(1) sp.while ( (i.value < lenCtr.value) & (i.value < sp.len(self.data.bids)) ): price_i.value = 0 jc.value = i.value + oneNat sp.while ( jc.value < (lenCtr.value + 1) ): price_i.value = price_i.value + (self.data.bids[jc.value] * (self.data.ctrs[sp.as_nat(sp.to_int(jc.value) - 1)] - self.data.ctrs[jc.value])) jc.value += 1 self.data.prices[i.value] = price_i.value i.value += 1 del self.data.ctrs[lenCtr.value]
def withdrawPayout(self): sp.verify(self.data.result.is_some()) sp.if self.data.result.open_some() == Position.Long: sp.verify(self.data.sharesLong.contains(sp.sender)) totalPayout = sp.local('totalPayout', 0) sp.for i in self.data.sharesLong[sp.sender].keys(): sp.if self.data.sharesLong[sp.sender][i] > 0: totalPayout.value += (sp.as_nat(self.data.sharesLong[sp.sender][i]) * 1000000)
def get_redeem_addresses(self, get_redeem_address_request): """As per FA2 standard, takes balance_of requests and reponds on the provided callback contract""" sp.set_type(get_redeem_address_request, RedeemAddress.get_request_type()) responses = sp.local("responses", sp.set_type_expr(sp.list([]),RedeemAddress.get_batch_type())) sp.for token_id in get_redeem_address_request.token_ids: sp.verify(self.data.token_metadata.contains(token_id), message = FA2ErrorMessage.TOKEN_UNDEFINED) responses.value.push(sp.record(token_id = token_id, address = self.data.token_context[token_id].redeem_address))
def total_supply(self, params): sp.verify( ~self.data.paused ) res = sp.local("responses", []) sp.set_type(res.value, Total_supply.response_type()) sp.for req in params.token_ids: res.value.push( sp.record( token_id = req, total_supply = self.data.tokens[req].total_supply))