Ejemplo n.º 1
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'])
Ejemplo n.º 2
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)
Ejemplo n.º 3
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())
Ejemplo n.º 4
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()}
Ejemplo n.º 5
0
 def tokens_contract_update():
     request = app.current_request
     data = request.json_body
     Database.update(
         "Token", {"symbol": data["symbol"]}, {
             "address": Web3Helper.toChecksumAddress(data["tokenAddress"]),
         })
     token = Database.find_one("Token", {"symbol": data["symbol"]})
     owner = Database.find_one(
         "User", {"address": Web3Helper.toChecksumAddress(data["owner"])})
     tokenBalance = Database.find_one("TokenBalance", {
         "tokenId": token['id'],
         "userId": owner["id"]
     })
     if not tokenBalance:
         tokenBalance = Database.find_one("TokenBalance", {
             "tokenId": token['id'],
             "userId": owner["id"],
             "balance": data['initialAmount']
         },
                                          insert=True)
     return toObject(token)
Ejemplo n.º 6
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"}
Ejemplo n.º 7
0
  def funds_post():
    request = app.current_request
    data = request.json_body
    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')

    fund_data = {
      "name": data["name"],
      "ownerId": ownerId
    }

    fund = Database.find_one('Fund', fund_data, insert=True)

    for token in data["tokens"]:
      token_data = {
        "name": data["name"],
        "fundId": fund["id"],
        "decimals": token["decimals"],
        "symbol": token["symbol"],
        "cutoffTime": int(token["cutoffTime"]),
        "fee": int(token["fee"]),
        "ownerId": ownerId,
        "currency": token["currency"],
        "initialAmount": token["initialAmount"],
        "incomeCategory": token["incomeCategory"],
        "minimumOrder": token["minimumOrder"]
      }
      if "nav" in token: token_data["nav"] = token['nav']
      if "holdings" in token: token_data["holdings"] = token["holdings"]
      token = createToken(token_data)

    return toObject(fund)
Ejemplo n.º 8
0
from chalicelib.truelayer import Truelayer as TL
from chalicelib.database import Database
from chalicelib.web3helper import Web3Helper
from chalice import Response, NotFoundError
from chalicelib.web3helper import Web3Helper
import os, json, random

front_end_url = os.environ.get('FRONT_END', 'http://*****:*****@app.route('/truelayer')
    def truelayer():
        request = app.current_request
        if 'id' not in request.query_params: raise NotFoundError('id')
        user_id = request.query_params['id']
        user = Database.find_one('User', {'id': user_id})
        nonce = ''.join(
            random.choice("qwertyuioplkjhgfdsazxvbnm") for _ in range(10))
        Database.update('User', {"id": int(user["id"])}, {"nonce": nonce})
        url = TL.get_auth_url(nonce)
        return Response(body=None, status_code=302, headers={"Location": url})
Ejemplo n.º 9
0
import jwt, os, json, requests, math, arrow, copy
from chalicelib.database import Database
from chalicelib.truelayer import Truelayer as TL
from datetime import datetime, date
from chalice import NotFoundError, ForbiddenError
from chalicelib.web3helper import Web3Helper
from chalicelib.cryptor import Cryptor
from chalicelib.utilities import *

socket_uri = os.environ.get("SOCKET_URI", None)
assert socket_uri != None

tradeKernelContract = Web3Helper.getContract("TradeKernel.json")

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:
Ejemplo n.º 10
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
Ejemplo n.º 11
0
from chalicelib.database import Database
from datetime import datetime
from chalice import NotFoundError, ForbiddenError
from chalicelib.web3helper import Web3Helper
from chalicelib.cryptor import Cryptor
from chalicelib.utilities import *
import jwt, os, json, arrow, math, hashlib
from chalicelib.endpoints.trade import takeFunds

# Set the signature on the contract
token_factory_contract = Web3Helper.getContract("TokenFactory.json")


def createHoldingsString(_holdings):
    holdings = [{
        'securityId': h['securityId'],
        'securityAmount': h['securityAmount']
    } for h in _holdings]
    holdings = sorted(holdings, key=lambda x: x['securityId'])
    holdingsString = json.dumps(holdings, separators=(',', ':'))
    # print(holdingsString)
    return holdingsString


def getBalances(tokenId):
    token = Database.find_one("Token", {"id": int(tokenId)})
    if not token:
        raise NotFoundError("token not found with id {}".format(tokenId))
    tokenBalances = Database.find("TokenBalance", {"tokenId": token["id"]})
    for tokenBalance in tokenBalances:
        investor = Database.find_one(