Skip to content

System Service Payment

The "System Service Payment" module is a system smart contract responsible for processing payments for services of Ace Network.

This smart contract is used solely for processing payments in favor of Ace Network. It should be noted that this does not include any mutual payments between network users, as well as payments for services in which DAO Ace Stream does not receive a fee (for example, system payments related to prediction market).

Payment Algorithm

  • if the payer has enough XAT then only XAT are used
  • if the payer is short of XAT then the difference is paid with XAB:
    • the required amount of XAB is calculated with the exchange module
    • this amount of XAB is being charged from the payer and burned
    • if the lockedPool is not empty then the same amount of XAB is put into circulation (moved from lockedPool to unlockedPool)
    • if the lockedPool is empty (i.e. all XAB are already unlocked) then the corresponding amount of XAT is automatically created and credited to the system pool targetPool (to be distributed by the terms of Ace Assets)


def makeSystemServicePayment(sourceAccount, amount, targetPool):
    sourceAccount - the payer account
    amount - amount of payment in XAT
    targetPool - system pool that will receive the payment
    if sourceAccount.balance.xat >= amount:
        # Source account has enough XAT

        # Move `amount` XAT from the source account to the target pool
        sourceAccount.balance.xat -= amount
        targetPool.balance.xat += amount
        # Source account doesn't have enough XAT

        # Amount of XAT user has
        xatAmount = sourceAccount.balance.xat

        # Amount of XAT needed to complete the payment
        amountLeft = amount - xatAcount

        # Amount of XAB needed based on system DEX exchange rate
        exchangeRate = DEX.getRate('XAT', 'XAB')
        xabAmount = amountLeft * exchangeRate

        if sourceAccount.balance.xab >= xabAmount:
            # Move `xatAmount` XAT from the source account to the target pool
            sourceAccount.balance.xat -= xatAmount
            targetPool.balance.xat += xatAmount

            # Burn `xabAmount` XAB from the source account
            sourceAccount.balance.xab -= xabAmount
            System.BLACKHOLE.balance.xab += xabAmount

            if System.lockedPool.amount >= xabAmount:
                # Unlock `xabAmount` XAB
                System.lockedPool.amount -= xabAmount
                System.unlockedPool.amount += xabAmount
                # How many XAB to unlock (all available)
                toUnlock = System.lockedPool.amount

                # How many XAB should be replaced with XAT
                xabToReplace = xabAmount - toUnlock

                # Unlock `toUnlock` XAB
                if toUnlock > 0:
                    System.lockedPool.amount -= toUnlock
                    System.unlockedPool.amount += toUnlock

                # emit `xatToEmit` XAT based on system DEX exchage rate
                xatToEmit = xabToReplace / exchangeRate
                targetPool.balance.xat += xatToEmit
            raise Exception('not enough tokens')


Examples are available here