def get_maker_fee(asset_id): storage = MCTManager() key = concat("makerFee", asset_id) fee = storage.get(key) if len(fee) != 0 or len(asset_id) == 0: return fee return storage.get("makerFee")
def get_offers(trading_pair) -> list: ''' Get List of Offers for trading pair :param trading_pair: scripthash of each contract trading pair :return: list of Offers() ''' storage = MCTManager() result_serialized = storage.get(trading_pair) if not result_serialized: print("result_serialized is null") return None result_info = storage.deserialize(result_serialized) offers = [] for result in result_info: offer = 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 get_volume(bucket_number, asset_id): storage = MCTManager() volume_key = concat("tradeVolume", bucket_number) volume_key = concat(volume_key, asset_id) volume_data = storage.get(volume_key) if len(volume_data) == 0: return Volume() else: return storage.deserialize(volume_data)
def transfer_asset_to(address, asset_id, amount): storage = MCTManager() if amount < 1: Notify("Amount to transfer less than 1!") return key = concat(address, asset_id) current_balance = storage.get(key) storage.put(key, current_balance + amount)
def get_offer(trading_pair, hash) -> Offer: ''' Get Single Offer :param trading_pair: :param hash: :return: Offer Object ''' storage = MCTManager() offer_data = storage.get(trading_pair + hash) if len(offer_data) == 0: return Offer() else: return storage.deserialize(offer_data)
def make_offer(offer) -> bool: ''' 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 = hash(offer) storage = MCTManager() if storage.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 add_volume(asset_id, native_amount, foreign_amount): time = GetTime() storage = MCTManager() bucket_number = time / bucket_duration volume_key = concat("tradeVolume", bucket_number) volume_key = concat(volume_key, asset_id) volume_data = storage.get(volume_key) if len(volume_data) == 0: volume = Volume() volume.Native = native_amount volume.Foreign = foreign_amount else: volume = storage.deserialize(volume_data) volume.Native = volume.Native + native_amount volume.Foreign = volume.Foreign + foreign_amount storage.put(volume_key, storage.serialize_array(volume))
def reduce_balance(address, asset_id, amount): storage = MCTManager() if amount < 1: Notify("Amount to reduce less than 1") return False key = concat(address, asset_id) current_balance = storage.get(key) new_balance = current_balance - amount if new_balance < 0: Notify("Not enough balance") return False if new_balance > 0: storage.put(key, new_balance) else: storage.delete(key) return True
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) storage = MCTManager() 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 = storage.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_state(): storage = MCTManager() return storage.get('state')
def get_balance(originator, asset_id): storage = MCTManager() key = concat(originator, asset_id) return storage.get(key)