예제 #1
0
def takeFunds(trade):
  print("Taking funds", trade['state'])
  decrypted = Cryptor.decryptInput(trade['nominalAmount'], trade['sk'])
  price = Cryptor.decryptInput(trade['price'], trade['sk'])

  # Ill need to include the currency here
  amountInvested = int(decrypted.split(':')[1])
  if trade['state'] != 4:
    return {'message': 'Trade is in state {}, requires state 4'.format(trade['state'])}

  # if amountInvested > 0:
  #   # First move the funds from the investors bank account to the brokers account
  #   moved = TL.move_funds(trade['brokerId'], trade['investorId'])
  #   if not moved:
  #     # Need to alert the smart contract that this trade hasn't worked
  #     return {'message': "Funds have not been moved, tokens not distributed"}
  # else:
  #   # Selling the tokens
  #   # First move the funds from the investors bank account to the brokers account
  #   moved = TL.move_funds(trade['investorId'], trade['brokerId'])
  #   if not moved:
  #     # Need to alert the smart contract that this trade hasn't worked
  #     return {'message': "Funds have not been moved, tokens not sold"}

  tx = Web3Helper.transact(
    tradeKernelContract,
    'transferFunds',
    trade['hash'],
  )
  print(tx.hex())
예제 #2
0
    def user_put(userId):
        request = app.current_request
        data = request.json_body

        if 'address' in data:
            # Find if another user
            # requestingUser = request.user
            data['address'] = Web3Helper.toChecksumAddress(data['address'])
            # user = Database.find_one("User", {'address': data['address']})
            # if user and user['id'] != requestingUser['id']:
            #   raise ForbiddenError('user already exists with address {}'.format(data['address']))

        user = Database.find_one("User", {'id': int(userId)})
        if not user:
            raise NotFoundError('user not found with id {}'.format(userId))
        user = Database.update('User', {'id': user['id']},
                               data,
                               return_updated=True)[0]

        if 'address' in data:
            # Set user athorized as investor
            tx = Web3Helper.transact(permissions_contract, 'setAuthorized',
                                     data['address'], 1)

        return toObject(
            user, ['id', 'name', 'address', 'role', 'ik', 'spk', 'signature'])
예제 #3
0
    def tokens_nav_update():
        print('\n\n\n\n')
        request = app.current_request
        data = request.json_body
        token = Database.find_one("Token", {"address": data["token"]})
        time = data["time"]
        executionDate = arrow.get(time).format('YYYY-MM-DD')
        nav = Database.insert("NAVTimestamp", {
            "tokenId": token['id'],
            "price": data['value'],
            "executionDate": executionDate
        },
                              return_inserted=True)

        # First need to collect the trades
        print(token['id'])
        trades = Database.find("Trade", {"state": 1, "tokenId": token["id"]})
        print(trades)
        # Need to go through each trade and get the NAV+price
        supplyUpdate = 0
        for trade in trades:
            decryptedNominalAmount = Cryptor.decryptInput(
                trade['nominalAmount'], trade['sk'])
            amountInvested = int(decryptedNominalAmount.split(':')[1])
            price = Cryptor.decryptInput(trade['price'], trade['sk'])
            price = float(price)
            print("amountInvested: ", amountInvested)
            print("price: ", price)
            effectiveNAV = (1.0 + float(price) / 100) * nav['price']
            print("supplyUpdate", int(amountInvested * 1.0 / effectiveNAV))
            # supplyUpdate += int(amountInvested * math.pow(10, token['decimals']) / nav['price'])
            supplyUpdate += int(amountInvested *
                                math.pow(10, token['decimals']) / effectiveNAV)

        tokenContract = Web3Helper.getContract("ETT.json", token['address'])

        # Update trades to be ready for claiming
        tradeQuery = [[('id', '=', t['id'])] for t in trades]
        trades = Database.update("Trade",
                                 tradeQuery, {'state': 4},
                                 return_updated=True)
        for trade in trades:
            # Take funds
            takeFunds(trade)
        tx = Web3Helper.transact(
            tokenContract,
            'updateTotalSupply',
            supplyUpdate,
            '',  # we are ignoring this for now
            executionDate)
        # tx = b''
        print(tx.hex())

        return toObject(nav)
예제 #4
0
  def trades_claim(tradeId):
    trade = Database.find_one("Trade", {"id": int(tradeId)})
    decrypted = Cryptor.decryptInput(trade['nominalAmount'], trade['sk'])
    price = Cryptor.decryptInput(trade['price'], trade['sk'])

    # Ill need to include the currency here
    amountInvested = int(decrypted.split(':')[1])
    if trade['state'] != 5:
      return {'message': 'Trade is in state {}, requires state 5'.format(trade['state'])}

    # get trade dates nav
    nav = Database.find_one("NAVTimestamp", {"tokenId": trade["tokenId"]}, order_by='-createdAt')
    # get todays nav and totalSupply
    token = Database.find_one('Token', {'id': trade['tokenId']})

    totalTokens = int(amountInvested / nav['price'])

    investorTokens = None
    if amountInvested > 0:
      effectiveNAV = (1.0+float(price)/100)*nav['price']
      investorTokens = amountInvested / effectiveNAV
    else:
      investorTokenBalance = Database.find_one("TokenBalance", {"tokenId": token["id"], "userId": investor["id"]})
      if not investorTokenBalance['balance']: investorTokenBalance['balance'] = '0'
      effectiveNAV = (1-float(price)/100)*nav['price']
      investorTokens =  min(int(amountInvested / effectiveNAV), -1 * int(investorTokenBalance['balance']))

    tokenContract = Web3Helper.getContract("ETT.json", token['address'])
    totalSupply = Web3Helper.call(tokenContract,'dateTotalSupply',arrow.get(trade['executionDate']).format('YYYY-MM-DD'),)

    # find number of tokens user allocated
    numberTokens = 0 if not nav['price'] else math.floor(amountInvested * totalSupply / nav['price'])
    investorTokens = int(investorTokens * math.pow(10, token['decimals']))

    # now ask the contract to distribute the tokens (maybe should be the investor that does this)
    investor = Database.find_one("User", {"id": trade["investorId"]})
    tradeKernelContract = Web3Helper.getContract("TradeKernel.json")
    tx = Web3Helper.transact(
      tradeKernelContract,
      'distributeTokens',
      trade['hash'],
      [
        Web3Helper.toChecksumAddress(token['address']),
        Web3Helper.toChecksumAddress(investor['address']),
      ],
      [
        investorTokens
      ]
    )
    print(tx.hex())
    Database.update("Trade", {"id": trade["id"]}, {"state": 6, "numberTokens": numberTokens})
    return {"message": "Tokens distributed"}
예제 #5
0
  def orders_complete():
    request = app.current_request
    data = request.json_body
    order = Database.find_one("Order", {"hash": data["orderHash"]})

    # set order state to complete
    Database.update("Order", {"id": order["id"]}, {"state": 1})

    # set state to all trade as verified
    orderTrades = Database.find("OrderTrade", {"orderId": order["id"]})
    tradeIds = [o['tradeId'] for o in orderTrades]
    tradeQuery = [[('id','=',tradeId)] for tradeId in tradeIds]
    Database.update("Trade", tradeQuery, {'state': 2})

    # Here I need to check if all orders are complete for the day
    executionDate = order["executionDate"]
    incompleteOrders = Database.find("Order", {"state": 0, "executionDate": executionDate, "tokenId": order["tokenId"]})
    if len(incompleteOrders):
      # There are still orders waiting to complete
      print("There are still orders waiting to complete")
      return {"message": "Order completed"}

    # Here I need to calculate the AUM
    # find the token
    token = Database.find_one("Token", {"id": order["tokenId"]})
    print(token['address'])
    tokenContract = Web3Helper.getContract("ETT.json", token['address'])

    tokenHoldingsObject = Database.find_one("TokenHoldings", {"tokenId": token["id"]})
    tokenHoldings = Database.find("TokenHolding", {"tokenHoldingsId": tokenHoldingsObject["id"]})

    newAUM = 0
    for tokenHolding in tokenHoldings:
      securityTimestamp = Database.find_one('SecurityTimestamp', {'securityId': tokenHolding["securityId"]}, order_by='-createdAt')
      newAUM += securityTimestamp['price'] * tokenHolding['securityAmount']

    executionDateString = arrow.get(executionDate).format('YYYY-MM-DD')

    tx = Web3Helper.transact(tokenContract, 'endOfDay', executionDateString)
    # tx = b''
    print({"message": "AUM updated", "AUM": newAUM, "hash": tx.hex()})
    return {"message": "AUM updated", "AUM": newAUM, "hash": tx.hex()}
예제 #6
0
def createToken(data):
    owner = None
    ownerId = data["ownerId"] if "ownerId" in data else None
    if not ownerId:
        owner = Database.find_one("User", {"address": Web3Helper.account()})
        ownerId = owner["id"]
    else:
        owner = Database.find_one("User", {"id": ownerId})

    if not owner: raise NotFoundError('No user found')

    token_data = {
        "fundId": data["fundId"],
        "decimals": data["decimals"],
        "symbol": data["symbol"],
        "cutoffTime": int(data["cutoffTime"]),
        "fee": int(data["fee"]),
        "ownerId": ownerId,
        "name": data["name"],
        "totalSupply": data["initialAmount"],
        "incomeCategory": data["incomeCategory"],
        "minimumOrder": data["minimumOrder"],
        "currency": data["minimumOrder"],
    }

    if "fundId" in data: token_data["fundId"] = data["fundId"]

    # Check if a token with the same symbol already exists
    symbolToken = Database.find_one("Token", {"symbol": token_data["symbol"]})
    if (symbolToken): raise ForbiddenError("Already a token with this symbol")

    token = Database.find_one("Token", token_data, insert=True)

    tokenHoldings = Database.find_one(
        "TokenHoldings", {
            "tokenId": token['id'],
            "executionDate": str(datetime.today().date())
        },
        insert=True)

    if 'nav' in data:
        # Create a NAV timestamp
        executionDate = arrow.now().format('YYYY-MM-DD')
        Database.insert(
            "NAVTimestamp", {
                "tokenId": token['id'],
                "price": data['nav'],
                "executionDate": executionDate
            })

    holdings = []

    if 'holdings' in data:
        for holding in data['holdings']:
            # get the correct security
            security = Database.find_one("Security",
                                         {"symbol": holding["symbol"]})
            if (security):
                Database.update("Security", {"id": security["id"]}, {
                    "name": holding["name"],
                    "currency": holding["currency"],
                    "country": holding["country"],
                    "sector": holding["sector"],
                    "class": holding["class"]
                })
            else:
                security = Database.find_one("Security", {
                    "symbol": holding["symbol"],
                    "name": holding["name"],
                    "currency": holding["currency"],
                    "country": holding["country"],
                    "sector": holding["sector"],
                    "class": holding["class"]
                },
                                             insert=True)

            price = holding['price'] if 'price' in holding else '0'
            securityTimestamp = Database.find_one('SecurityTimestamp', {
                'securityId': security["id"],
                'price': price
            },
                                                  order_by='-createdAt',
                                                  insert=True)
            tokenHolding = Database.find_one(
                "TokenHolding", {
                    "securityId": security["id"],
                    "securityAmount": holding["amount"],
                    "tokenHoldingsId": tokenHoldings["id"]
                },
                insert=True)
            holdings.append(tokenHolding)

    holdingsString = createHoldingsString(holdings)

    try:
        tx = Web3Helper.transact(
            token_factory_contract,
            'createETT',
            token_data["name"],
            token_data["decimals"],
            token_data["symbol"],
            int(data["initialAmount"]),
            holdingsString,
            token_data["cutoffTime"],
            token_data["fee"],
            Web3Helper.toChecksumAddress(owner['address']),
        )
        print(tx.hex())
    except Exception as e:
        print(e)
        pass