Example #1
0
def sts_add_to_total_circulation(sts: SmartTokenShare, amount: int):
    """
    Adds an amount of token to circlulation

    Args:
        sts (SmartTokenShare):
            Smart Token Share object containing specific attributes

        amount (int):
            amount of tokens added
    """
    storage = StorageManager()

    # Calculation
    sts.total_in_circulation = sts.total_in_circulation + amount

    # output STS info
    updated_sts_info = [
        sts.symbol, sts.decimals, sts.owner, sts.total_supply,
        sts.total_in_circulation
    ]

    # Save STS info
    updated_sts_info_serialized = storage.serialize_array(updated_sts_info)
    storage.put_double('STS', sts.project_id, updated_sts_info_serialized)
Example #2
0
    def test_add_to_total_circulation(self):
        sts = SmartTokenShare()

        # Setting default info
        storage = StorageManager()
        storage.put_double('STS', self.test_project_id, self.test_sts_info)

        # Running add_to_total_circulation()
        sts.add_to_total_circulation(self.test_project_id,
                                     self.test_add_amount)
        sts.add_to_total_circulation(self.test_project_id,
                                     self.test_add_amount)
        sts.add_to_total_circulation(self.test_project_id,
                                     self.test_add_amount)

        in_circ = sts.get_total_circulation(self.test_project_id)

        test_in_circ = self.test_add_amount * 3

        # Check Test
        if in_circ == test_in_circ:
            print('test_add_to_total_circulation PASSED')
            return True

        print('test_add_to_total_circulation FAILED')
        return False
Example #3
0
def fr_list_append(project_id, key, new_item):
    """Adds the input list of funding stages to storage (as serialized array)
    Args:
        project_id (list): ID for referencing the project
        new_list (list): list of funding stages to save to storage
    """
    storage = StorageManager()

    print('new_item')
    print(new_item)

    # Gets current stored list
    current_serialized_list = storage.get_double(project_id, key)

    # Converts serialized list to normal list
    current_list = storage.deserialize_bytearray(current_serialized_list)
    current_list_len = len(current_list)
    print('current_list_len')
    print(current_list_len)

    if current_list_len == 0:
        output_list = [new_item]

    else:
        output_list = current_list
        output_list.append(new_item)

    # Serializes list
    serialized_output_list = storage.serialize_array(output_list)
    print('serialized_output_list')
    print(serialized_output_list)

    # Saves updated serialized list to storage
    storage.put_double(project_id, key, serialized_output_list)
    def do_approve(self, project_id, t_owner, t_spender, amount):
        storage = StorageManager()

        if not CheckWitness(t_owner):
            print("Incorrect permission")
            return False

        from_balance = storage.get_double(project_id, t_owner)

        # cannot approve an amount that is
        # currently greater than the from balance
        if from_balance >= amount:

            approval_key = concat(t_owner, t_spender)

            current_approved_balance = storage.get_double(
                project_id, approval_key)

            new_approved_balance = current_approved_balance + amount

            storage.put_double(project_id, approval_key, new_approved_balance)

            OnApprove(project_id, t_owner, t_spender, amount)

            return True

        return False
Example #5
0
def fr_set_active_index(project_id, idx):
    """    
    Sets the active index
    Args:
        project_id (list): ID for referencing the project
        idx (int): new active index    
    """
    storage = StorageManager()
    storage.put_double(project_id, 'FR_active_idx', idx)
Example #6
0
def fs_claim_system_fee(fs: FundingStage, system_owner_addr):
    storage = StorageManager()

    if CheckWitness(system_owner_addr):

        # If the funding stage complted sucessfully
        if fs_status(fs) == 1:

            # Calculating fee
            fee_calculated = fs_calculate_system_fee(fs)

            # Sets the claim amount for the address, as 10^8
            storage.put_double('CLAIM', system_owner_addr, fee_calculated)

            return True

    return False
Example #7
0
def sts_create(project_id, symbol, decimals, owner,
               total_supply) -> SmartTokenShare:
    """
    Args:
        project_id (str):
            ID for referencing the project

        symbol (str):
            Representation symbol
            
        decimals (int):
            Amount of decimal places, default 8

        owner (bytes):
            Owner of the token

        total_supply (int):
            total supply of the token
    Return:
        (SmartTokenShare): 
            Returns a Smart Token Share object containing these attributes
    """
    # init objects
    storage = StorageManager()
    sts = SmartTokenShare()

    # Saves vars to object
    sts.project_id = project_id
    sts.symbol = symbol
    sts.decimals = decimals
    sts.owner = owner
    sts.total_supply = total_supply

    # Default circulation
    sts.total_in_circulation = 0

    # Info structure
    sts_info = [symbol, decimals, owner, total_supply, 0]

    # Will only save to storage if none exsits for this project_id
    if not storage.get_double('STS', project_id):
        sts_info_serialized = storage.serialize_array(sts_info)
        storage.put_double('STS', project_id, sts_info_serialized)

    return sts
Example #8
0
    def test_exchange(self):

        fs = FundingStage()
        attachments = get_asset_attachments()

        # Test vars
        tokens_per_gas = 100
        test_exchanged_sts = attachments.gas_attached * tokens_per_gas / 100000000

        # Sets balance to 0
        storage = StorageManager()
        storage.put_double(self.test_project_id, attachments.sender_addr, 0)

        # Registers KYC address
        storage.put_triple(self.test_project_id, 'KYC_address',
                           self.test_address1, True)

        # Setting default info
        storage = StorageManager()
        storage.delete_triple('FS', self.test_project_id,
                              self.test_funding_stage_id)

        # Creates new test fund
        fs.create(self.test_project_id, self.test_funding_stage_id, 1, 999999,
                  10000, tokens_per_gas)

        # Testing exchange method and checking stored balance
        fs.exchange(self.test_project_id, self.test_funding_stage_id)
        result1 = storage.get_double(self.test_project_id,
                                     attachments.sender_addr)

        # Testing exchange method and checking stored balance again (should double)
        fs.exchange(self.test_project_id, self.test_funding_stage_id)
        result2 = storage.get_double(self.test_project_id,
                                     attachments.sender_addr)

        # Check Test
        print('CHECK')

        if result1 == test_exchanged_sts and result2 == test_exchanged_sts * 2:
            print('test_exchange PASSED')
            return True

        print('test_exchange FAILED')
        return False
    def do_transfer(self, project_id, t_from, t_to, amount):
        storage = StorageManager()

        # Pointless
        if amount <= 0:
            return False

        # Validate address
        if CheckWitness(t_from):

            # Pointless
            if t_from == t_to:
                print("transfer to self!")
                return True

            from_val = storage.get_double(project_id, t_from)

            if from_val < amount:
                print("insufficient funds")
                return False

            if from_val == amount:
                storage.delete_double(project_id, t_from)

            else:
                difference = from_val - amount
                storage.put_double(project_id, t_from, difference)

            to_value = storage.get_double(project_id, t_to)

            to_total = to_value + amount

            storage.put_double(project_id, t_to, to_total)

            OnTransfer(project_id, t_from, t_to, amount)

            return True
        else:
            print("from address is not the tx sender")

        return False
Example #10
0
def fs_claim_contributions(fs: FundingStage, owner_addr):
    """
    This is required to prep a claim for a verification transaction
    Args:
        fs (FundingStage):
            Funding Stage object containing specific attributes

        owner_addr (bytearray):
            Address of the claim deposit address
    
    Return:
        (bool):
            Can Claim
    """
    storage = StorageManager()
    if CheckWitness(owner_addr):

        # If the funding stage complted sucessfully
        if fs_status(fs) == 1:

            # Checks the owner_addr matches the sts project owner
            sts = sts_get(fs.project_id)
            if sts_get_attr(sts, 'owner') == owner_addr:

                # Calculates the gas amount contributed, decimal safe 10^8
                gas_contributed = fs.in_circulation / fs.tokens_per_gas * 100000000

                # Calculating fee
                fee_calculated = fs_calculate_system_fee(fs)

                # Deducting fees
                gas_to_claim = gas_contributed - fee_calculated

                # Sets the claim amount for the address, as 10^8
                storage.put_double('CLAIM', owner_addr, gas_to_claim)
                return True

    return False
Example #11
0
def fs_refund(fs: FundingStage, refund_addr):
    """
    This is required to prep a refund for for a verification transaction
    Args:
        fs (FundingStage):
            Funding Stage object containing specific attributes

        refund_addr (bytearray):
            Address of the refund address in question
    
    Return:
        (bool):
            Can Refund
    """
    storage = StorageManager()

    if CheckWitness(refund_addr):

        # If the funding stage failed
        if fs_status(fs) != 1:

            # lookup the current balance of the address
            current_sts_balance = fs_get_addr_balance(fs, refund_addr)

            # Calculate gas from current_sts_balance
            gas_contribution = current_sts_balance / fs.tokens_per_gas * 100000000

            # unlocks current_sts_balance to refund_addr, as 10^8
            storage.put_double('CLAIM', refund_addr, gas_contribution)

            # sets refund_addr balance to 0
            fs_set_addr_balance(fs, refund_addr, 0)

            return True

    return False
    def do_transfer_from(self, project_id, t_from, t_to, amount):

        storage = StorageManager()
        if amount <= 0:
            return False

        available_key = concat(t_from, t_to)

        available_to_to_addr = storage.get_double(project_id, available_key)

        if available_to_to_addr < amount:
            print("Insufficient funds approved")
            return False

        from_balance = storage.get_double(project_id, t_from)

        if from_balance < amount:
            print("Insufficient tokens in from balance")
            return False

        to_balance = storage.get_double(project_id, t_to)

        new_from_balance = from_balance - amount

        new_to_balance = to_balance + amount

        storage.put_double(project_id, t_to, new_to_balance)
        storage.put_double(project_id, t_from, new_from_balance)

        print("transfer complete")

        new_allowance = available_to_to_addr - amount

        if new_allowance == 0:
            print("removing all balance")
            storage.delete_double(project_id, available_key)
        else:
            print("updating allowance to new allowance")
            storage.put_double(project_id, available_key, new_allowance)

        OnTransfer(project_id, t_from, t_to, amount)

        return True
Example #13
0
def claim_clean(addr):
    storage = StorageManager()
    attachments = get_asset_attachments()
    
    storage.put_double('CLAIM', attachments.sender_addr, 0)
Example #14
0
    def test(self, operation, args):

        storage = StorageManager()
        attachments = get_asset_attachments()

        if operation == 'create_all':
            print('create_all')

            sts_create(self.project_id, self.symbol, self.decimals, self.owner,
                       self.total_supply)
            fs_create(self.project_id, 'first_stage', 1, 999999, 1000, 100)
            fs_create(self.project_id, 'second_stage', 1, 12750, 500, 100)
            fs_create(self.project_id, 'third_stage', 1, 12450, 100, 100)
            fs_create(self.project_id, 'fourth_stage', 1, 99999, 200, 100)

            fss = [
                'first_stage', 'second_stage', 'third_stage', 'fourth_stage'
            ]

            ms_create(self.project_id, 'first_mile', 'First', 'sub', 'hash')
            ms_create(self.project_id, 'second_mile', 'First', 'sub', 'hash')
            ms_create(self.project_id, 'third_mile', 'First', 'sub', 'hash')
            ms_create(self.project_id, 'fourth_mile', 'First', 'sub', 'hash')

            mss = ['first_mile', 'second_mile', 'third_mile', 'fourth_mile']

            admins = [self.owner]

            fr_add_funding_stages(self.project_id, fss)
            fr_add_milestones(self.project_id, mss)
            fr_add_project_admins(self.project_id, admins)
            fr_set_active_index(self.project_id, 0)

            return True

        if operation == 'get_funding_stages':
            print('get_funding_stages')

            stages = fr_get_funding_stages(self.project_id)
            print(stages)

            return stages

        if operation == 'kyc':
            print('attachments.sender_addr')
            print(attachments.sender_addr)
            storage.put_triple(self.project_id, 'KYC_address', self.owner,
                               True)

        if operation == 'calim_test':
            storage.put_double('CLAIM', attachments.sender_addr,
                               attachments.gas_attached)

        if operation == 'contribute':
            print('#contribute')
            # Registers KYC address
            storage.put_triple(self.project_id, 'KYC_address',
                               attachments.sender_addr, True)

            active_idx = fr_get_active_index(self.project_id)
            funding_stages = fr_get_funding_stages(self.project_id)
            active_funding_stage = funding_stages[active_idx]

            fs = fs_get(self.project_id, active_funding_stage)

            fs_contribute(fs)
            # storage.put_double('CLAIM', attachments.sender_addr, attachments.gas_attached)
            print('contribute#')

        if operation == 'get_idx':
            active_idx = fr_get_active_index(self.project_id)
            print(active_idx)
            return active_idx

        if operation == 'get_active_fs':
            active_idx = fr_get_active_index(self.project_id)
            funding_stages = fr_get_funding_stages(self.project_id)
            active_funding_stage = funding_stages[active_idx]
            print(active_funding_stage)
            return active_funding_stage

        # 4 Put == (1 GAS per KB)
        # 7 Get == 0.7 GAS
        if operation == 'contribute_fs':
            print('#contribute_fs')

            active_funding_stage = args[0]

            fs = fs_get(self.project_id, active_funding_stage)
            fs_contribute(fs)

            print('contribute_fs#')

        if operation == 'balance':
            print('balance')
            # bal = storage.get_double(self.project_id, attachments.sender_addr)
            fs_id = args[0]
            addr = args[1]

            fs = fs_get('projectID', fs_id)
            bal = fs_get_addr_balance(fs, addr)
            print(bal)

        if operation == 'funding_stage_status':
            print('#funding_stage_status')
            active_idx = fr_get_active_index(self.project_id)
            funding_stages = fr_get_funding_stages(self.project_id)
            active_funding_stage = funding_stages[active_idx]

            fs = fs_get(self.project_id, active_funding_stage)
            status = fs_status(fs)

            print('funding_stage_status#')
            print(status)
            return status

        if operation == 'current_index':
            active_idx = fr_get_active_index(self.project_id)
            print(active_idx)
            return active_idx

        if operation == 'milestone_progress':
            print('#milestone_progress')
            active_idx = fr_get_active_index(self.project_id)
            milestones = fr_get_milestones(self.project_id)
            active_milestone = milestones[active_idx]

            ms = ms_get(self.project_id, active_milestone)
            prog = ms_get_progress(ms)
            print('milestone_progress#')
            print(prog)
            return prog

        if operation == 'complete_milestone':
            print('complete_milestone')
            fr_update_milestone_progress(self.project_id, 100)

        if operation == 'sts_get':
            sts = sts_get('projectID')
            arg = args[0]

            if arg == 'project_id':
                return sts.project_id

            if arg == 'symbol':
                return sts.symbol

            if arg == 'decimals':
                return sts.decimals

            if arg == 'owner':
                return sts.owner

            if arg == 'total_supply':
                return sts.total_supply

            if arg == 'total_in_circulation':
                return get_total_in_circulation(sts)

        if operation == 'fs_get':
            active_idx = fr_get_active_index('projectID')
            funding_stages = fr_get_funding_stages('projectID')
            active_funding_stage = funding_stages[active_idx]

            fs = fs_get('projectID', active_funding_stage)

            arg = args[0]
            # attr = fs_get_attr(fs, arg)

            if arg == 'project_id':
                return fs.project_id

            if arg == 'funding_stage_id':
                return fs.funding_stage_id

            if arg == 'start_block':
                return fs.start_block

            if arg == 'end_block':
                return fs.end_block

            if arg == 'supply':
                return fs.supply

            if arg == 'tokens_per_gas':
                return fs.tokens_per_gas

            if arg == 'in_circulation':
                return get_in_circulation(fs)

        if operation == 'fs_claim_contributions':
            fs_id = args[0]
            deposit_addr = args[1]
            fs = fs_get('projectID', fs_id)
            fs_claim_contributions(fs, deposit_addr)

        if operation == 'fs_claim_fee':
            print('fs_claim_fee')
            fs_id = args[0]
            owner_addr = b'j\x1agL0\xff\x926\x02\xde.a\x1fR\xe3FT\x0f\xba|'
            fs = fs_get('projectID', fs_id)
            fs_claim_system_fee(fs, owner_addr)

        if operation == 'fs_refund':
            fs_id = args[0]
            refund_addr = args[1]
            fs = fs_get('projectID', fs_id)
            fs_refund(fs, refund_addr)

        return True
Example #15
0
def Main(operation, args):
    """Entry point for the smart contract.
    Args:
        operation (str):
            UUID used as the first part of the key for Storage.Put().
        args (str):
            UUID used as the second part of the key for Storage.Put().
    Return:
        (bytearray): The result of the operation
    """

    # Gets the transaction trigger
    trigger = GetTrigger()
    storage = StorageManager()

    invalid_args_msg = 'INVALID ARGS'
    invaild_op_msg = 'INVALID OPERATION'

    if trigger == Verification:
        print('Verification')

        attachments = get_asset_attachments()
        prev_attachments = get_asset_attachments_for_prev()

        gas_requested = prev_attachments.gas_attached - attachments.gas_attached
        print(gas_requested)

        # Get amount avaliable for address
        claim_amount = storage.get_double('CLAIM', attachments.receiver_addr)

        # If the request is the EXACT amount (not less), approve the tx
        if claim_amount == gas_requested:
            print('Successfully send claim tx')
            return True

    elif trigger == Application:
        print('Application')

        kyc = KYC()

        #    F U N D I N G    R O A D M A P   #

        project_id = args[0]

        sts = sts_get(project_id)

        # ARGS: project_id, refund_addr
        if operation == 'check_claim_owed':
            OnOperationInvoke('check_claim_owed')
            print('execute:check_claim_owed')
            if len(args) == 2:
                refund_addr = args[1]
                return storage.get_double('CLAIM', refund_addr)

        # ARGS: project_id, refund_addr
        if operation == 'reset_claim_owed':
            OnOperationInvoke('reset_claim_owed')
            print('execute:reset_claim_owed')
            if len(args) == 2:
                refund_addr = args[1]
                return storage.put_double('CLAIM', refund_addr, 0)

        # ARGS: project_id, new_admin
        if operation == 'add_project_admins':
            OnOperationInvoke('add_project_admins')
            print('execute:add_project_admins')
            if len(args) == 2:
                if CheckWitness(sts.owner):
                    new_admin = args[1]
                    fr_add_project_admin(project_id, new_admin)
                    return True
            return invalid_args_msg

        # ARGS: project_id
        if operation == 'get_active_index':
            OnOperationInvoke('get_active_index')
            print('execute:get_active_index')
            if len(args) == 1:
                return fr_get_active_index(project_id)
            return invalid_args_msg

        # ARGS: project_id
        if operation == 'get_funding_stages':
            OnOperationInvoke('get_funding_stages')
            print('execute:get_funding_stages')
            if len(args) == 1:
                funding_stages = fr_get_funding_stages(project_id)
                return funding_stages
            return invalid_args_msg

        # ARGS: project_id
        if operation == 'get_active_fs':
            OnOperationInvoke('get_active_fs')
            print('execute:get_active_fs')
            if len(args) == 1:
                active_idx = fr_get_active_index(project_id)
                funding_stages = fr_get_funding_stages(project_id)
                active_funding_stage = funding_stages[active_idx]
                return active_funding_stage
            return invalid_args_msg

        # ARGS: project_id
        if operation == 'get_milestones':
            OnOperationInvoke('get_milestones')
            print('execute:get_milestones')
            if len(args) == 1:
                milestones = fr_get_milestones(project_id)
                return milestones
            return invalid_args_msg

        # ARGS: project_id
        if operation == 'get_active_ms':
            OnOperationInvoke('get_active_ms')
            print('execute:get_active_ms')
            if len(args) == 1:
                active_idx = fr_get_active_index(project_id)
                milestones = fr_get_milestones(project_id)
                active_milestone = milestones[active_idx]
                return active_milestone
            return invalid_args_msg

        # ARGS: project_id, updated_progress
        if operation == 'update_active_ms_progress':
            OnOperationInvoke('update_active_ms_progress')
            print('execute:update_active_ms_progress')
            if len(args) == 2:
                if CheckWitness(sts.owner):
                    updated_progress = args[1]

                    progress = fr_update_milestone_progress(
                        project_id, updated_progress)

                    return progress
            return invalid_args_msg

        #    S M A R T    T O K E N    S H A R E   #

        # ARGS: project_id, symbol, decimals, owner, total_supply
        if operation == 'create_sts':
            OnOperationInvoke('create_sts')
            print('execute:create_sts')
            if len(args) == 5:
                symbol = args[1]
                decimals = 8  # hardcoded to 8
                owner = args[3]
                total_supply = args[4]

                sts_create(project_id, symbol, decimals, owner, total_supply)
                fr_set_active_index(project_id, 0)
                return project_id
            return invalid_args_msg

        # ARGS: project_id, attribute: {'project_id', 'symbol', 'decimals', 'owner', 'total_supply', 'total_in_circulation'}
        if operation == 'sts_attribute':
            OnOperationInvoke('sts_attribute')
            print('execute:sts_attribute')
            if len(args) == 2:
                attr = args[1]

                sts = sts_get(project_id)
                return sts_get_attr(sts, attr)
            return invalid_args_msg

        # ARGS: project_id
        if operation == 'total_tokens_available':
            OnOperationInvoke('total_tokens_available')
            print('execute:total_tokens_available')
            if len(args) == 1:

                sts = sts_get(project_id)
                return sts_total_available_amount(sts)
            return invalid_args_msg

        #    F U N D I N G    S T A G E   #

        funding_stage_id = args[1]

        # ARGS: project_id, funding_stage_id, start_block, end_block, supply, tokens_per_gas
        if operation == 'create_fs':
            OnOperationInvoke('create_fs')
            print('execute:create_fs')
            if len(args) == 6:
                if CheckWitness(sts.owner):
                    start_block = args[2]
                    end_block = args[3]
                    supply = args[4]
                    tokens_per_gas = args[5]

                    fs_create(project_id, funding_stage_id, start_block,
                              end_block, supply, tokens_per_gas)
                    fr_add_funding_stage(project_id, funding_stage_id)
                    return funding_stage_id
            return invalid_args_msg

        # ARGS: project_id, funding_stage_id, attribute: {'project_id', 'funding_stage_id', 'start_block', 'end_block', 'supply', 'tokens_per_gas', 'in_circulation'}
        if operation == 'fs_attribute':
            OnOperationInvoke('fs_attribute')
            print('execute:fs_attribute')
            if len(args) == 3:
                attr = args[2]

                fs = fs_get(project_id, funding_stage_id)
                return fs_get_attr(fs, attr)

        # ARGS: project_id, funding_stage_id
        if operation == 'fs_tokens_available':
            OnOperationInvoke('fs_tokens_available')
            print('execute:fs_tokens_available')
            if len(args) == 2:

                fs = fs_get(project_id, funding_stage_id)
                return fs_available_amount(fs)
            return invalid_args_msg

        # ARGS: project_id, funding_stage_id
        if operation == 'fs_status':
            OnOperationInvoke('fs_status')
            print('execute:fs_status')
            if len(args) == 2:

                fs = fs_get(project_id, funding_stage_id)
                return fs_status(fs)
            return invalid_args_msg

        # ARGS: project_id, funding_stage_id
        if operation == 'fs_contribute':
            OnOperationInvoke('fs_contribute')
            print('execute:fs_contribute')
            if len(args) == 2:

                fs = fs_get(project_id, funding_stage_id)
                return fs_contribute(fs)
            return invalid_args_msg

        # ARGS: project_id, funding_stage_id, addr
        if operation == 'fs_addr_balance':
            OnOperationInvoke('fs_addr_balance')
            print('execute:fs_addr_balance')
            if len(args) == 2:
                addr = args[2]
                fs = fs_get(project_id, funding_stage_id)
                return fs_get_addr_balance(fs, addr)
            return invalid_args_msg

        #     M I L E S T O N E    #

        milestone_id = args[1]

        # ARGS: project_id, milestone_id, title, subtitle, extra_info_hash
        if operation == 'create_ms':
            OnOperationInvoke('create_ms')
            print('execute:create_ms')
            if len(args) == 5:
                if CheckWitness(sts.owner):
                    title = args[2]
                    subtitle = args[3]
                    extra_info_hash = args[4]

                    ms_create(project_id, milestone_id, title, subtitle,
                              extra_info_hash)
                    fr_add_milestone(project_id, milestone_id)
                    return milestone_id
            return invalid_args_msg

        # ARGS: project_id, milestone_id, attribute: {'project_id', 'milestone_id', 'title', 'subtitle', 'extra_info_hash', 'progress'}
        if operation == 'ms_attribute':
            OnOperationInvoke('ms_attribute')
            print('execute:ms_attribute')
            if len(args) == 3:
                attr = args[2]

                ms = ms_get(project_id, milestone_id)
                return ms_get_attr(ms, attr)

        # ARGS: project_id, milestone_id
        if operation == 'get_ms_progess':
            OnOperationInvoke('get_ms_progess')
            print('execute:get_ms_progess')
            if len(args) == 2:
                ms = ms_get(project_id, milestone_id)
                return ms_get_progress(ms)
            return invalid_args_msg

        #    C L A I M S   #

        funding_stage_id = args[1]

        # ARGS: project_id, funding_stage_id, refund_addr
        if operation == 'claim_fs_refund':
            OnOperationInvoke('claim_fs_refund')
            print('execute:claim_fs_refund')
            if len(args) == 3:
                refund_addr = args[2]

                fs = fs_get(project_id, funding_stage_id)
                return fs_refund(fs, refund_addr)
            return invalid_args_msg

        # ARGS: project_id, funding_stage_id, owner_addr
        if operation == 'claim_fs_contributions':
            OnOperationInvoke('claim_fs_contributions')
            print('execute:claim_fs_contributions')
            if len(args) == 3:
                owner_addr = args[2]

                fs = fs_get(project_id, funding_stage_id)
                return fs_claim_contributions(fs, owner_addr)
            return invalid_args_msg

        # ARGS: project_id, funding_stage_id, system_owner_addr
        if operation == 'claim_fs_system_fee':
            OnOperationInvoke('claim_fs_system_fee')
            print('execute:claim_fs_system_fee')
            if len(args) == 3:
                system_owner_addr = args[2]

                fs = fs_get(project_id, funding_stage_id)
                return fs_claim_system_fee(fs, system_owner_addr)
            return invalid_args_msg

        #   K Y C   #

        # ARGS: project_id, address, phys_address, first_name, last_name, id_type, id_number, id_expiry, file_location, file_hash
        if operation == 'kyc_submit':
            OnOperationInvoke('kyc_submit')
            print('execute:kyc_submit')
            if len(args) == 10:
                address = args[1]
                phys_address = args[2]
                first_name = args[3]
                last_name = args[4]
                id_type = args[5]
                id_number = args[6]
                id_expiry = args[7]
                file_location = args[8]
                file_hash = args[9]

                kyc.kyc_submit(project_id, address, phys_address, first_name,
                               last_name, id_type, id_number, id_expiry,
                               file_location, file_hash)
                return address
            return invalid_args_msg

        # ARGS: project_id, addresses ->
        if operation == 'kyc_register':
            if CheckWitness(sts.owner):
                OnOperationInvoke('kyc_register')
                print('execute:kyc_register')
                if len(args) > 1:
                    # addresses = args[1:]

                    return kyc.kyc_register(project_id, args)
            return invalid_args_msg

        # ARGS: project_id, address
        if operation == 'kyc_status':
            OnOperationInvoke('kyc_status')
            print('execute:kyc_status')
            if len(args) == 2:
                address = args[1]

                return kyc.kyc_status(project_id, address)
            return invalid_args_msg

        # ARGS: project_id, address
        if operation == 'get_kyc_submission':
            OnOperationInvoke('get_kyc_submission')
            print('execute:get_kyc_submission')
            if len(args) == 2:
                address = args[1]

                return kyc.get_kyc_submission(project_id, address)
            return invalid_args_msg

        return invaild_op_msg