ArFlash
  • 💸ArFlash - Flashing Processes
  • Overview
    • 👨‍🚀What do we do ?
    • ✨Our Features
  • Use Cases
    • 📪For Liquidity Providers
    • 📎For Borrowers?
    • 🐻For Arflash?
  • Specification
    • 🦁ArFlash Token Specification
    • 👾FlashLoan Reciever Specification
    • 🐋ArFlash Handlers
  • How it works?
    • 🐸How it works?
Powered by GitBook
On this page
  • Token Configuration Documentation
  • Parameters Overview
  • 🗨️Info
  • 🖐️Handlers

Was this helpful?

  1. Specification

ArFlash Token Specification

Token Configuration Documentation

This document provides a comprehensive overview of the LP (liqudity tokens) or token Standard by the Arflash Protocol. ArFlash protocol is dependent on this token standard.

Parameters Overview

  1. Balances: A table maintaining user balances. If not initialized, it is created automatically.

  2. Allowances: A table used for managing the allowances given by token holders. It initializes itself if absent.

  3. Name: The name of the token. Defaults to 'TOKENNAME' if not correctly defined.

  4. Symbol (Ticker): Represents the tick symbol of the token. Defaults to 'COIN' if not set appropriately.

  5. Denomination: Specifies the number of token units constituting a single whole unit for display. It defaults to 10.

  6. Logo: A URL linking to the token's logo image. It defaults to an empty string if not specified.

🗨️Info


local json = require('json')

if not Balances then Balances = {} end
if not Allowances then Allowances = {} end

if Name ~= 'TOKENNAME' then Name = 'TOKENNAME' end


-- Symbol
if Ticker ~= 'COIN' then Ticker = 'COIN' end

-- The number of the token that should be treated as a single unit when quantities and balances are displayed to users.	
if Denomination ~= 10 then Denomination = 10 end

-- lOGO link
if not Logo then Logo = '' end

🖐️Handlers

Info Handler


Handlers.add('info', Handlers.utils.hasMatchingTag('Action', 'Info'), function(msg)
  ao.send({
    Target = msg.From,
    Tags = { Name = Name, Ticker = Ticker, Logo = Logo, Denomination = tostring(Denomination) }
  })
end)

Usage :

Send({ Target = ao.id, Action = "Info" })

Retrieving Data

Inbox[#Inbox].Tags

Balance Handler

Check the balance of a specific account or the sender's account.

  Handlers.add('balance', Handlers.utils.hasMatchingTag('Action', 'Balance'), function(msg)
    local bal = '0'

    -- If not Target is provided, then return the Senders balance
    if (msg.Tags.Target and Balances[msg.Tags.Target]) then
      bal = tostring(Balances[msg.Tags.Target])
    elseif Balances[msg.From] then
      bal = tostring(Balances[msg.From])
    end

    local targetAccount = msg.Tags.Target or msg.From

    ao.send({
      Target = msg.From,
      Tags = { Target = targetAccount, Balance = bal, Ticker = Ticker, Data = json.encode(tonumber(bal)) }
    })
  end)

Check the balance of a specific account or the sender's account.

Usage

Send({ Target = ao.id, Tags = { Action = "Balance", Target = 'wallet or processid' }})
   Send({ Target = ao.id, Tags = { Action = "Balance" } })

Retrieving Data

   Inbox[#Inbox].Tags

Balances Handler

Retrieve the balances of all accounts.

  Handlers.add('balances', Handlers.utils.hasMatchingTag('Action', 'Balances'),
              function(msg) ao.send({ Target = msg.From, Data = json.encode(Balances) }) end)

Usage :

   Send({ Target = ao.id, Tags = { Action = "Balances" } })
   Inbox[#Inbox].Data

Transfer Handler

Transfer tokens to another wallet or process ID.

  Handlers.add('transfer', Handlers.utils.hasMatchingTag('Action', 'Transfer'), function(msg)
    assert(type(msg.Tags.Recipient) == 'string', 'Recipient is required!')
    assert(type(msg.Tags.Quantity) == 'string', 'Quantity is required!')

    if not Balances[msg.From] then Balances[msg.From] = 0 end

    if not Balances[msg.Tags.Recipient] then Balances[msg.Tags.Recipient] = 0 end

    local qty = tonumber(msg.Tags.Quantity)
    assert(type(qty) == 'number', 'qty must be number')

    if Balances[msg.From] >= qty then
      Balances[msg.From] = Balances[msg.From] - qty
      Balances[msg.Tags.Recipient] = Balances[msg.Tags.Recipient] + qty

      --[[
        Only Send the notifications to the Sender and Recipient
        if the Cast tag is not set on the Transfer message
      ]] --
      if not msg.Tags.Cast then
        -- Debit-Notice message template, that is sent to the Sender of the transfer
        local debitNotice = {
          Target = msg.From,
          Action = 'Debit-Notice',
          Recipient = msg.Recipient,
          Quantity = tostring(qty),
          Data = Colors.gray ..
              "You transferred " ..
              Colors.blue .. msg.Quantity .. Colors.gray .. " to " .. Colors.green .. msg.Recipient .. Colors.reset
        }
        -- Credit-Notice message template, that is sent to the Recipient of the transfer
        local creditNotice = {
          Target = msg.Recipient,
          Action = 'Credit-Notice',
          Sender = msg.From,
          Quantity = tostring(qty),
          Data = Colors.gray ..
              "You received " ..
              Colors.blue .. msg.Quantity .. Colors.gray .. " from " .. Colors.green .. msg.From .. Colors.reset
        }

        -- Add forwarded tags to the credit and debit notice messages
        for tagName, tagValue in pairs(msg) do
          -- Tags beginning with "X-" are forwarded
          if string.sub(tagName, 1, 2) == "X-" then
            debitNotice[tagName] = tagValue
            creditNotice[tagName] = tagValue
          end
        end

        -- Send Debit-Notice and Credit-Notice
        ao.send(debitNotice)
        ao.send(creditNotice)
      end
    else
      ao.send({
        Target = msg.Tags.From,
        Tags = { Action = 'Transfer-Error', ['Message-Id'] = msg.Id, Error = 'Insufficient Balance!' }
      })
    end
  end)

Transfer tokens to another wallet or process ID.

Send({ Target = ao.id, Tags = { Action = "Transfer", Recipient = 'another wallet or processid', Quantity = '10000' }})

Notifications:

  • Debit Notice to the sender:

    {
      Target = "sender_wallet_or_processid",
      Action = "Debit-Notice",
      Recipient = "recipient_wallet_or_processid",
      Quantity = "10000"
    }
  • Credit Notice to the recipient:

    {
      Target = "recipient_wallet_or_processid",
      Action = "Credit-Notice",
      Sender = "sender_wallet_or_processid",
      Quantity = "10000"
    }

Allowance Handler

Check the allowance set for a spender by the owner.

  Handlers.add('allowance', Handlers.utils.hasMatchingTag('Action', 'Allowance'), function(msg)
    local allowance = '0'
    if Allowances[msg.From] and Allowances[msg.From][msg.Tags.Spender] then
      allowance = tostring(Allowances[msg.From][msg.Tags.Spender])
    end

    ao.send({
      Target = msg.From,
      Tags = { Owner = msg.From, Spender = msg.Tags.Spender, Allowance = allowance }
    })
  end) 

Check the allowance set for a spender by the owner.

Send({ Target = ao.id, Tags = { Action = "Allowance", Spender = 'spender wallet or processid' }})
Inbox[#Inbox].Tags.Allowance

Approve Handler

Set the allowance for a spender.

  Handlers.add('approve', Handlers.utils.hasMatchingTag('Action', 'Approve'), function(msg)
    assert(type(msg.Tags.Spender) == 'string', 'Spender is required!')
    assert(type(msg.Tags.Quantity) == 'string', 'Quantity is required!')

    if not Allowances[msg.From] then Allowances[msg.From] = {} end

    local qty = tonumber(msg.Tags.Quantity)
    assert(type(qty) == 'number', 'qty must be number')

    Allowances[msg.From][msg.Tags.Spender] = qty

    ao.send({
      Target = msg.From,
      Tags = { Action = 'Approval', Spender = msg.Tags.Spender, Quantity = tostring(qty) }
    })
  end)
Send({ Target = ao.id, Tags = { Action = "Approve", Spender = 'spender wallet or processid', Quantity = '5000' }})    
Inbox[#Inbox].Tags

TransferFrom handler

Transfer tokens from an owner's account to a recipient's account using the allowance system.

Handlers.add('transferFrom', Handlers.utils.hasMatchingTag('Action', 'TransferFrom'), function(msg)
  assert(type(msg.Tags.from) == 'string', 'From is required!')
  assert(type(msg.Tags.to) == 'string', 'To is required!')
  assert(type(msg.Tags.Quantity) == 'string', 'Quantity is required!')

  -- Convert quantity to number
  local from = msg.Tags.from
  local to = msg.Tags.to
  local qty = tonumber(msg.Tags.Quantity)
  assert(qty ~= nil, 'Quantity must be a valid number!')
  assert(qty > 0, 'Quantity must be greater than zero!')

  -- Ensure balances and allowances tables exist
  if not Balances[from] then Balances[from] = 0 end
  if not Balances[to] then Balances[to] = 0 end
  if not Allowances[from] then Allowances[from] = {} end

  -- Check allowance and balances
  local allowance = Allowances[from][msg.From] or 0
  assert(allowance >= qty, 'Allowance exceeded!')
  assert(Balances[from] >= qty, 'Insufficient Balance!')

  -- Perform transfer
  Balances[from] = Balances[from] - qty
  Balances[to] = Balances[to] + qty
  Allowances[from][msg.From] = allowance - qty

  -- Send success notifications
  ao.send({
    Target = msg.From,
    Tags = {
      Action = 'TransferFrom-Notice',
      From = from,
      To = to,
      Quantity = tostring(qty)
    }
  })
  ao.send({
    Target = from,
    Tags = {
      Action = 'Debit-Notice',
      To = to,
      Quantity = tostring(qty),
      Data = "Your tokens were transferred to " .. to
    }
  })
  ao.send({
    Target = to,
    Tags = {
      Action = 'Credit-Notice',
      From = from,
      Quantity = tostring(qty),
      Data = "You received tokens from " .. from
    }
  })
end)

Transfer tokens on behalf of an owner using the allowance.

Send({
  Target = ao.id,
  Tags = {
    Action = "TransferFrom",
    from = "from_wallet_or_processid",
    to = "to_wallet_or_processid",
    Quantity = "3000"
  }
})

Minting Handler

Mint new tokens and add them to the sender's balance.


  Handlers.add('mint', Handlers.utils.hasMatchingTag('Action', 'Mint'), function(msg)
    assert(type(msg.Tags.Quantity) == 'string', 'Quantity is required!')
    local qty = tonumber(msg.Tags.Quantity)
    assert(type(qty) == 'number', 'qty must be number')

    if msg.From == env.Process.Id then
      -- Add tokens to the token pool, according to Quantity
      Balances[msg.From] = Balances[msg.From] + qty
      ao.send({
        Target = msg.From,
        Tags = { Action = 'Mint-Notice', Quantity = tostring(qty), Balance = tostring(Balances[msg.From]) }
      })
    else
      ao.send({
        Target = msg.From,
        Tags = { Action = 'Mint-Error', ['Message-Id'] = msg.Id, Error = 'Unauthorized minting attempt!' }
      })
    end
  end)

Mint new tokens to the token pool.

   Send({ Target = ao.id, Tags = { Action = "Mint", Quantity = "1000" } })

Burn Handler

Burn tokens from the sender's account.

Handlers.add('burn', Handlers.utils.hasMatchingTag('Action', 'Burn'), function(msg)
    assert(type(msg.Tags.Quantity) == 'string', 'Quantity is required!')
    local qty = tonumber(msg.Tags.Quantity)
    assert(type(qty) == 'number', 'qty must be number')

    if msg.From == env.Process.Id then
      if not Balances[msg.From] then Balances[msg.From] = 0 end

      if Balances[msg.From] >= qty then
        Balances[msg.From] = Balances[msg.From] - qty

        ao.send({
          Target = msg.From,
          Tags = { Action = 'Burn-Notice', Quantity = tostring(qty), Balance = tostring(Balances[msg.From]) }
        })
      else
        ao.send({
          Target = msg.From,
          Tags = { Action = 'Burn-Error', ['Message-Id'] = msg.Id, Error = 'Insufficient Balance!' }
        })
      end
    else
      ao.send({
        Target = msg.From,
        Tags = { Action = 'Burn-Error', ['Message-Id'] = msg.Id, Error = 'Unauthorized burning attempt!' }
      })
    end
  end)
Send({ Target = ao.id, Tags = { Action = "Burn", Quantity = '2000' }})

PreviousFor Arflash?NextFlashLoan Reciever Specification

Last updated 5 months ago

Was this helpful?

🦁