def get_taker_fee(asset_id): key = concat("takerFee", asset_id) fee = get(key) if len(fee) != 0 or len(asset_id) == 0: return fee return get("takerFee")
def make_offer(offer): ''' Make New Offer on books :param offer: :return: Result of if offer was valid ''' if not CheckWitness(offer["MakerAddress"]): return False # Checking that the person that invoked this was the smart contract it self if not CheckWitness(OWNER): return False allowed = get("state") if allowed == 'Inactive' or allowed == 'Pending': return False if (allowed == 'Terminated' and not offer["OfferAssetID"] == NeoAssetID and offer["WantAssetID"] == GasAssetID and not offer["WantAssetID"] == NeoAssetID and offer["OfferAssetID"] == GasAssetID): return False trading_pair = offer["OfferAssetID"] + offer["WantAssetID"] offer_hash = serialize_array(offer) if get(trading_pair + offer_hash): return False if not offer["OfferAmount"] > 0 and offer["WantAmount"] > 0: return False if offer["OfferAssetID"] == offer["WantAssetID"]: return False if (len(offer["OfferAssetID"]) != 20 and len(offer["OfferAssetID"]) != 32 or len(offer["WantAssetID"]) != 20 and len(offer["WantAssetID"]) != 32): return False if not reduce_balance(offer["MakerAddress"], offer["OfferAssetID"], offer["OfferAmount"]): return False store_offer(trading_pair, offer_hash, offer) created(offer["MakerAddress"], offer_hash, offer["OfferAssetID"], offer["OfferAmount"], offer["WantAssetID"], offer["WantAmount"]) return True
def get_offers(trading_pair): ''' Get List of Offers for trading pair :param trading_pair: scripthash of each contract trading pair :return: list of Offers() ''' result_serialized = get(trading_pair) if not result_serialized: print("result_serialized is null") return False result_info = deserialize(result_serialized) offers = [] for result in result_info: offer = create_offer() offer["MakerAddress"] = result["MakerAddress"] offer["OfferAssetID"] = result["OfferAssetID"] offer["OfferAssetCategory"] = result["OfferAssetCategory"] offer["OfferAmount"] = result["OfferAmount"] offer["WantAssetID"] = result["WantAssetID"] offer["WantAssetCategory"] = result["WantAssetCategory"] offer["WantAmount"] = result["WantAmount"] offer["AvailableAmount"] = result["AvailableAmount"] offer["TradingPair"] = result["OfferAssetCategory"] + result[ "WantAssetCategory"] offers.append(offer) return offers
def transfer_asset_to(address, asset_id, amount): if amount < 1: Notify("Amount to transfer less than 1!") return key = concat(address, asset_id) current_balance = get(key) put(key, current_balance + amount)
def get_volume(bucket_number, asset_id): volume_key = concat("tradeVolume", bucket_number) volume_key = concat(volume_key, asset_id) volume_data = get(volume_key) if len(volume_data) == 0: return set_volume() else: return deserialize(volume_data)
def get_offer(trading_pair, hash): ''' Get Single Offer :param trading_pair: :param hash: :return: Offer Object ''' offer_data = get(trading_pair + hash) if len(offer_data) == 0: return create_offer() else: return deserialize(offer_data)
def reduce_balance(address, asset_id, amount): if amount < 1: Notify("Amount to reduce less than 1") return False key = concat(address, asset_id) current_balance = get(key) new_balance = current_balance - amount if new_balance < 0: Notify("Not enough balance") return False if new_balance > 0: put(key, new_balance) else: delete(key) return True
def add_volume(asset_id, native_amount, foreign_amount): time = GetTime() bucket_number = time / bucket_duration volume_key = concat("tradeVolume", bucket_number) volume_key = concat(volume_key, asset_id) volume_data = get(volume_key) if len(volume_data) == 0: volume = set_volume() volume["Native"] = native_amount volume["Foreign"] = foreign_amount else: volume = deserialize(volume_data) volume["Native"] = volume["Native"] + native_amount volume["Foreign"] = volume["Foreign"] + foreign_amount put(volume_key, serialize_array(volume))
def main(operation, args): trigger = GetTrigger() if trigger == Verification(): ''' Validate inputs Check that valid self send Validate is withdrawing nep5 Validate utxo has been reserved Validate withdraw destination Validate amount withdrawn ''' if get("state") != 'Active': return False tx_data = get_asset_attachments() prev_tx_data = get_asset_attachments_for_prev() # THIS WILL NEED TO BE CALLING A FUNCTION LATER withdrawal_stage = 'Mark' if withdrawal_stage == 'Mark': if not CheckWitness(tx_data["sender_addr"]): return False ''' if not verify_withdrawal(tx_data): return False // Validate inputs as well foreach (var i in inputs) { if (Storage.Get(Context(), i.PrevHash.Concat(IndexAsByteArray(i.PrevIndex))).Length > 0) return false; } ''' tx = GetScriptContainer() inputs = GetInputs(tx) outputs = GetOutputs(tx) if CheckWitness(OWNER): return True return False elif trigger == Application(): if operation == 'initialize': if not CheckWitness(OWNER): print("initialize error") return False if len(args) != 3: print("To few args") return False return initialize() # Get functions if operation == 'getstate': return get("state") # ARGS: asset_id if operation == 'getMakerFee': return get_maker_fee(args[0]) # ARGS: asset_id if operation == 'getTakerFee': return get_taker_fee(args[0]) # ARGS: asset_id if operation == 'getExchangeRate': return get_exchange_rate(args[0]) # ARGS: trading_pair if operation == 'getOffers': return get_offers(args[0]) # ARGS: originator, asset_id if operation == 'getBalance': return get_balance(args[0], args[1]) # Execute functions # ARGS: address, asset_id, amount if operation == 'deposit': if get("state") != 'Active': return False if len(args) != 3: return False if not verify_sent_amount(args[0], args[1], args[2]): return False if not transfer_asset_to(args[0], args[1], args[2]): return False return True # ARGS: maker_address, offer_asset_id, offer_amount, want_asset_id, want_amount, avail_amount, nonce if operation == 'makeOffer': if get("state") != 'Active': return False if len(args) != 7: return False offer = new_offer(args[0], args[1], args[2], args[3], args[4], args[5], args[6]) return make_offer(offer) # ARGS: filler_address, trading_pair, offer_hash, amount_to_fill, use_native_token) if operation == 'fillOffer': if get("state") != 'Active': return False if len(args) != 5: return False return fill_offer(args[0], args[1], args[2], args[3], args[4]) # ARGS: trading_pair, offer_hash if operation == 'cancelOffer': if get("state") != 'Active': return False if len(args) != 2: return False return cancel_offer(args[0], args[1]) if operation == 'withdraw': return process_withdrawal() # Owner Operations if not CheckWitness(OWNER): return False if operation == 'freezeTrading': return freeze_trading() if operation == 'unfreezeTrading': return unfreeze_trading() if operation == 'terminateTrading': return terminate_trading() if operation == 'addToWhitelist': return add_to_whitelist() if operation == 'removeFromWhitelist': return remove_from_whitelist() # ARGS: amount if operation == 'ownerWithdraw': if not CheckWitness(OWNER): print( 'Only the contract owner can withdraw MCT from the contract' ) return False if len(args) != 1: print('withdraw amount not specified') return False t_amount = args[0] my_hash = GetExecutingScriptHash() return transfer(my_hash, t_amount) return False
def fill_offer(filler_address, trading_pair, offer_hash, amount_to_fill, use_native_token): if not CheckWitness(filler_address): return False # Checking that the person that invoked this was the smart contract if not CheckWitness(OWNER): return False offer = get_offer(trading_pair, offer_hash) if offer["MakerAddress"] == '': failed(filler_address, offer_hash) return False allowed = get("state") if allowed == 'Inactive' or allowed == 'Pending': return False if (allowed == 'Terminated' and not offer["OfferAssetID"] == NeoAssetID and offer["WantAssetID"] == GasAssetID and not offer["WantAssetID"] == NeoAssetID and offer["OfferAssetID"] == GasAssetID): return False if filler_address == offer["MakerAddress"]: return False amount_to_take = (offer["OfferAmount"] * offer["WantAmount"]) / offer["OfferAmount"] if amount_to_take > offer["AvailableAmount"]: amount_to_take = offer["AvailableAmount"] amount_to_fill = (amount_to_take * offer["WantAmount"]) / offer["OfferAmount"] if amount_to_take <= 0: failed(filler_address, offer_hash) return True fee_address = get('feeAddress') maker_fee_rate = get_maker_fee(offer["WantAssetID"]) taker_fee_rate = get_taker_fee(offer["OfferAssetID"]) maker_fee = (amount_to_fill * maker_fee_rate) / fee_factor taker_fee = (amount_to_take * taker_fee_rate) / fee_factor native_fee = 0 if use_native_token and offer["OfferAssetID"] != native_token: time = GetTime() bucket_number = time / bucket_duration volume = get_volume(bucket_number, offer["OfferAssetID"]) native_volume = volume["Native"] foreign_volume = volume["Foreign"] if foreign_volume > 0: native_fee = (taker_fee * native_volume) / (foreign_volume * native_token_discount) if not reduce_balance(filler_address, native_token, native_fee): native_fee = 0 if offer["OfferAssetID"] == native_token: taker_fee = taker_fee / native_token_discount if native_fee > 0: taker_amount = amount_to_take - taker_fee else: taker_amount = 0 # Transfer to taker transfer_asset_to(filler_address, offer["WantAssetID"], taker_amount) transferred(filler_address, offer["OfferAssetID"], taker_amount) # Transfer to maker maker_amount = amount_to_fill - maker_fee transfer_asset_to(offer["MakerAddress"], offer["WantAssetID"], maker_amount) transferred(offer["MakerAddress"], offer["WantAssetID"], maker_amount) # Move fees if maker_fee > 0: transfer_asset_to(fee_address, offer["WantAssetID, maker_fee"]) if native_fee == 0 and offer["OfferAssetID"] != native_token: transfer_asset_to(fee_address, offer["OfferAssetID"], taker_fee) # Update native token exchange rate if offer["OfferAssetID"] == native_token: add_volume(offer["WantAssetID"], amount_to_take, amount_to_fill) if offer["WantAssetID"] == native_token: add_volume(offer["OfferAssetID"], amount_to_fill, amount_to_take) # Update available amount offer["AvailableAmount"] = offer["AvailableAmount"] - amount_to_take store_offer(trading_pair, offer_hash, offer) filled(filler_address, offer_hash, amount_to_fill, offer["OfferAssetID"], offer["OfferAmount"], offer["WantAssetID"], offer["WantAmount"]) return True
def get_balance(originator, asset_id): key = concat(originator, asset_id) return get(key)