- Community: 92%
- 80% (TGE 0%): Community delegating
- 12% (TGE 0%): Pool Substake
- 1st year: 17%, then 4-year halving
- Ecosystem: 7%
- 2% (TGE 100%): TestNet
- 5% (TGE 100%): Pool Bootstrap
- Liquidity: 1% (TGE 100%)
This document outlines the token release schedule for AO tokens over a 41-year period.
- TGE (Time 0): 8% initial distribution
- Year 1: 17% total distribution
- Years 2-5: 37.5% total
- Years 6-9: 18.75% total
- Years 10-13: 9.375% total
- Years 14-17: 4.6875% total
- Following Years: Continue halving the growth increment
first run npm run init
All testcase should be under spec folder
npm run test -- entry.lua or
npm run test
Every testfile should be end with _spec.lua
Every testfile should contains
local luaunit = require('libs.luaunit')
luaunit.LuaUnit:setOutputType("tap")
luaunit:setVerbosity(luaunit.VERBOSITY_VERBOSE)
luaunit.LuaUnit.run()Run with aos console:
aos [process_name] --sqlite --cron 5-minute
.load apus_token/main.lua
.monitor
-
MintDb Return the database with memory address.
Apus@aos-2.0.1[Inbox:18]> MintDb sqlite database (0x618f688) -
DbAdmin Return the object DbAdmin(it has a member variable called db).
Apus@aos-2.0.1[Inbox:18]> DbAdmin { db = sqlite database (0x618f688) } -
Deposits Return the database connector to deposits.
Apus@aos-2.0.1[Inbox:18]> Deposits { dbAdmin = { db = sqlite database (0x618f688) } } -
Mint Return the mint module, members are mint-related functions. These functions can be found in
mint.lua.Apus@aos-2.0.1[Inbox:18]> Mint { currentMintAmount = function: 0x6253280, _version = "0.0.1", isCronBackup = function: 0x62534e0, mint = function: 0x6253220, batchUpdate = function: 0x6253140, mintBackUp = function: 0x6253480 }
-
Token Return the token module, members are token-related functions. These functions can be found in
token.lua.Apus@aos-2.0.1[Inbox:18]> Token { info = function: 0x6252a00, balances = function: 0x6252a60, _version = "0.0.1", burn = function: 0x62392a0, transfer = function: 0x6238fa0, mintedSupply = function: 0x6239240, totalSupply = function: 0x62391c0, balance = function: 0x6253600 }
-
Allocator Return the allocator module, members are allocator-related functions. These functions can be found in
allocator.lua.Apus@aos-2.0.1[Inbox:18]> Allocator { _version = "0.0.1", compute = function: 0x6239480 }
-
Distributor Return the distributor module, members are distributor-related functions. These functions can be found in
distributor.lua.Apus@aos-2.0.1[Inbox:18]> Distributor { getWallet = function: 0x6239820, bindingWallet = function: 0x6239760, _version = "0.0.1", testSetWallet = function: 0x6239940 }
-
AO_MINT_PROCESS Return the address of AO Mint Process.
Apus@aos-2.0.1[Inbox:18]> AO_MINT_PROCESS LPK-D_3gZkXtia6ywwU1wRwgFOZ-eLFRMP9pfAFRfuw -
APUS_STATS_PROCESS Return the address of Apus Stats Process
Apus@aos-2.0.1[Inbox:18]> APUS_STATS_PROCESS zmr4sqL_fQjjvHoUJDkT8eqCiLFEM3RV5M96Wd59ffU -
Initialized Return if the process has been initialized.
Apus@aos-2.0.1[Inbox:18]> Initialized true
-
Deposits.new(DbAdmin) Create a new client to process with the
rewardstable. This will trigger the create table operation. We can directly use theDbAdminas the parameter to create such an instance.Apus@aos-2.0.1[Inbox:18]> Deposits.new(DbAdmin) { dbAdmin = { db = sqlite database (0x618f688) } } -
Deposits:updateMintForUser(user, mint) This function is used to add mint for target user record. You can directly use
Depositsto call the functions. No need to get a new instance of Deposits.# select the record first. Apus@aos-2.0.1[Inbox:18]> Deposits:getByUser("0xEFb8a39cDcCC482EA0c92450BD0f6DF31201aF55") { User = "0xEFb8a39cDcCC482EA0c92450BD0f6DF31201aF55", Mint = "0", Recipient = "JyQiTvqKIXZczY57PWOnhELUBIIKc56xWAbcM2_MXrk" } # add mint for the user. Apus@aos-2.0.1[Inbox:18]> Deposits:updateMintForUser("0xEFb8a39cDcCC482EA0c92450BD0f6DF31201aF55", "2500") # select the record again to check Mint. Apus@aos-2.0.1[Inbox:18]> Deposits:getByUser("0xEFb8a39cDcCC482EA0c92450BD0f6DF31201aF55") { User = "0xEFb8a39cDcCC482EA0c92450BD0f6DF31201aF55", Mint = "2500", Recipient = "JyQiTvqKIXZczY57PWOnhELUBIIKc56xWAbcM2_MXrk" }
-
Deposits:getByUser(user) This function is used to select the record of one user.
Apus@aos-2.0.1[Inbox:18]> Deposits:getByUser("0xEFb8a39cDcCC482EA0c92450BD0f6DF31201aF55") { User = "0xEFb8a39cDcCC482EA0c92450BD0f6DF31201aF55", Mint = "0", Recipient = "JyQiTvqKIXZczY57PWOnhELUBIIKc56xWAbcM2_MXrk" }
-
Deposits:getAll() This function returns all the records in
rewardstable.Apus@aos-2.0.1[Inbox:18]> Deposits:getAll() { { User = "0x0d386297c95C7e48db734E3Eb2F476CD73f92E59", Mint = "0", Recipient = "" }, { User = "0xdA4Ef9B6d55176ab0760b8fe90152c699C91D16e", Mint = "0", Recipient = "" }, { User = "0xd0265Aa8A1b3b409F061F2AE4f39Cdbf1BA3A37a", Mint = "0", Recipient = "" }, { User = "0x6DCeB0F7Dd6bED4fF190D8cA74F67973C280f4B4", Mint = "0", Recipient = "" }, { User = "0x360d26B78eECB0DC96c3fC4d99512879916b35c4", Mint = "0", Recipient = "" }, { User = "lpJ5Edz_8DbNnVDL0XdbsY9vCOs45NACzfI4jvo4Ba8", Mint = "0", Recipient = "lpJ5Edz_8DbNnVDL0XdbsY9vCOs45NACzfI4jvo4Ba8" }, { User = "0x43C68e2C3Fc96b077d19e503a609a83Cb4D0c6fA", Mint = "0", Recipient = "" }, { User = "0x8f3D0284183aBdBe3345C8cE08Ec81413e82f38F", Mint = "0", Recipient = "lpJ5Edz_8DbNnVDL0XdbsY9vCOs45NACzfI4jvo4Ba8" }, { User = "0x7300782D46E385B1D0B4e831D48c4224F502ECb9", Mint = "0", Recipient = "lpJ5Edz_8DbNnVDL0XdbsY9vCOs45NACzfI4jvo4Ba8" }, { User = "0xEFb8a39cDcCC482EA0c92450BD0f6DF31201aF55", Mint = "0", Recipient = "JyQiTvqKIXZczY57PWOnhELUBIIKc56xWAbcM2_MXrk" } }
-
Deposits:getToAllocateUsers() This functions return the records filtered with the condition that Mint of the record should be greater than zero and recipient cannot be empty.
# empty because all the records have no mint. Apus@aos-2.0.1[Inbox:18]> Deposits:getToAllocateUsers() { } # add Mint for the target user. Apus@aos-2.0.1[Inbox:18]> Deposits:updateMintForUser("0xEFb8a39cDcCC482EA0c92450BD0f6DF31201aF55", "2500") # select again, the record can be found in the result. Apus@aos-2.0.1[Inbox:18]> Deposits:getToAllocateUsers() { { User = "0xEFb8a39cDcCC482EA0c92450BD0f6DF31201aF55", Mint = "2500", Recipient = "JyQiTvqKIXZczY57PWOnhELUBIIKc56xWAbcM2_MXrk" } }
-
Deposits:upsert(record) This function can insert(if the record with the record.User does not exist) or update(the record exists) the record.
# first select, no record found Apus@aos-2.0.1[Inbox:18]> Deposits:getByUser("test") # upsert the record with User equal to test Apus@aos-2.0.1[Inbox:18]> Deposits:upsert({User = "test", Recipient = "", Mint = "0"}) # second select, can get the record Apus@aos-2.0.1[Inbox:18]> Deposits:getByUser("test") { User = "test", Mint = "0", Recipient = "" } # upsert again, this can update the record.Mint Apus@aos-2.0.1[Inbox:18]> Deposits:upsert({User = "test", Recipient = "", Mint = "321321"}) # last select, check if upsert works. Apus@aos-2.0.1[Inbox:18]> Deposits:getByUser("test") { User = "test", Mint = "321321", Recipient = "" }
-
Deposits:clearMint() This function will clear all the records' Mint value.
# No users ready for allocation. Apus@aos-2.0.1[Inbox:18]> Deposits:getToAllocateUsers() { } # add mint for the target user. Apus@aos-2.0.1[Inbox:18]> Deposits:updateMintForUser("0xEFb8a39cDcCC482EA0c92450BD0f6DF31201aF55", "2500") # check if the user exists in the allocation list. Apus@aos-2.0.1[Inbox:18]> Deposits:getToAllocateUsers() { { User = "0xEFb8a39cDcCC482EA0c92450BD0f6DF31201aF55", Mint = "2500", Recipient = "JyQiTvqKIXZczY57PWOnhELUBIIKc56xWAbcM2_MXrk" } } # call clearMint() Apus@aos-2.0.1[Inbox:18]> Deposits:clearMint() # check again. Return empty table Apus@aos-2.0.1[Inbox:18]> Deposits:getToAllocateUsers() { }
- Allocator:compute(deposits, reward)
This function will calculate reward for each object in deposits list. The reward will be allocated according to their mint.
Apus@aos-2.0.1[Inbox:18]> Allocator:compute({{ User = "0x0d386297c95C7e48db734E3Eb2F476CD73f92E59", Mint = "1000000000000", Recipient = "" },{ User = "0xdA4Ef9B6d55176ab0760b8fe90152c699C91D16e", Mint = "2000000000000", Recipient = "" },{ User = "0xd0265Aa8A1b3b409F061F2AE4f39Cdbf1BA3A37a", Mint = "3000000000000", Recipient = "" }}, "100000") { { Reward = "16667", User = "0x0d386297c95C7e48db734E3Eb2F476CD73f92E59", Mint = "1000000000000", Recipient = "" }, { Reward = "33333", User = "0xdA4Ef9B6d55176ab0760b8fe90152c699C91D16e", Mint = "2000000000000", Recipient = "" }, { Reward = "50000", User = "0xd0265Aa8A1b3b409F061F2AE4f39Cdbf1BA3A37a", Mint = "3000000000000", Recipient = "" } }
-
Distributor.bindingWallet(wallet, recipient) This function will set recipient for the record with user equals to wallet.
# get the record first. Apus@aos-2.0.1[Inbox:18]> Deposits:getByUser("0xd0265Aa8A1b3b409F061F2AE4f39Cdbf1BA3A37a") { User = "0xd0265Aa8A1b3b409F061F2AE4f39Cdbf1BA3A37a", Mint = "0", Recipient = "" } # binding recipient for the user. Apus@aos-2.0.1[Inbox:18]> Distributor.bindingWallet("0xd0265Aa8A1b3b409F061F2AE4f39Cdbf1BA3A37a", "aa") # check if it works Apus@aos-2.0.1[Inbox:18]> Deposits:getByUser("0xd0265Aa8A1b3b409F061F2AE4f39Cdbf1BA3A37a") { User = "0xd0265Aa8A1b3b409F061F2AE4f39Cdbf1BA3A37a", Mint = "0", Recipient = "aa" }
-
Distributor.getWallet(wallet) Return the recipient for the target user.
# fetch the record first Apus@aos-2.0.1[Inbox:18]> Deposits:getByUser("0x8f3D0284183aBdBe3345C8cE08Ec81413e82f38F") { User = "0x8f3D0284183aBdBe3345C8cE08Ec81413e82f38F", Mint = "0", Recipient = "lpJ5Edz_8DbNnVDL0XdbsY9vCOs45NACzfI4jvo4Ba8" } # get the wallet, check if the return value is the recipient. Apus@aos-2.0.1[Inbox:18]> Distributor.getWallet("0x8f3D0284183aBdBe3345C8cE08Ec81413e82f38F") lpJ5Edz_8DbNnVDL0XdbsY9vCOs45NACzfI4jvo4Ba8
-
MINT_CAPACITY Return the capacity of the total mint schedule.
Apus@aos-2.0.1[Inbox:18]> MINT_CAPACITY 1000000000000000000000 -
APUS_MINT_PCT_1 Return the mint percent at the first stage.
Apus@aos-2.0.1[Inbox:18]> APUS_MINT_PCT_1 19421654225 -
APUS_MINT_PCT_2 Return the mint percent at the second stage.
Apus@aos-2.0.1[Inbox:18]> APUS_MINT_PCT_2 16473367976 -
APUS_MINT_UNIT Return the mint base.
Apus@aos-2.0.1[Inbox:18]> APUS_MINT_UNIT 10000000000000000 -
INTERVALS_PER_YEAR Return the intervals per year.
Apus@aos-2.0.1[Inbox:18]> INTERVALS_PER_YEAR 105192.0 -
DAYS_PER_MONTH Return the constant days of per month.
Apus@aos-2.0.1[Inbox:18]> DAYS_PER_MONTH 30.4375 -
INTERVALS_PER_MONTH Return the intervals per month.
Apus@aos-2.0.1[Inbox:18]> INTERVALS_PER_MONTH 8766 -
MintedSupply Return the minted supply.
Apus@aos-2.0.1[Inbox:18]> MintedSupply 80509095358650411831 -
MintTimes Return the minted times.
Apus@aos-2.0.1[Inbox:18]> MintTimes 286 -
MINT_COOL_DOWN Return the cooldown seconds of mint.
Apus@aos-2.0.1[Inbox:18]> MINT_COOL_DOWN 300 -
LastMintTime Return the last mint time.
Apus@aos-2.0.1[Inbox:18]> LastMintTime 1733854022 -
MODE Return the current mode (ON / OFF)
Apus@aos-2.0.1[Inbox:18]> MODE on -
Mint.batchUpdate(mintReportList) Update the rewards table according to the mint report.
# no users to allocate at first Apus@aos-2.0.1[Inbox:18]> Deposits:getToAllocateUsers() { } # batch update for the users in table. Apus@aos-2.0.1[Inbox:18]> Mint.batchUpdate({{User = "0x8f3D0284183aBdBe3345C8cE08Ec81413e82f38F", Mint = "22"}, {User = "0x7300782D46E385B1D0B4e831D48c4224F502ECb9", Mint = "11"}, {User="0xEFb8a39cDcCC482EA0c92450BD0f6DF31201aF55", Mint = "33"}}) OK # check again if it works Apus@aos-2.0.1[Inbox:18]> Deposits:getToAllocateUsers() { { User = "0x8f3D0284183aBdBe3345C8cE08Ec81413e82f38F", Mint = "22", Recipient = "lpJ5Edz_8DbNnVDL0XdbsY9vCOs45NACzfI4jvo4Ba8" }, { User = "0x7300782D46E385B1D0B4e831D48c4224F502ECb9", Mint = "11", Recipient = "lpJ5Edz_8DbNnVDL0XdbsY9vCOs45NACzfI4jvo4Ba8" }, { User = "0xEFb8a39cDcCC482EA0c92450BD0f6DF31201aF55", Mint = "33", Recipient = "JyQiTvqKIXZczY57PWOnhELUBIIKc56xWAbcM2_MXrk" } }
-
Mint.currentMintAmount() Return the amount of apus tokens to be allocated in the coming mint cycle.
Apus@aos-2.0.1[Inbox:18]> Mint.currentMintAmount() 1785796504653019
-
Mint.mint(msg) Mint as per
msg.Timestamp.Apus@aos-2.0.1[Inbox:18]> require("os").time() 1733854833674 Apus@aos-2.0.1[Inbox:18]> Mint.mint({Timestamp = 1733854833674}) Not cool down yet
-
Mint.mintBackUp(msg) Same with
Mint.mintApus@aos-2.0.1[Inbox:18]> require("os").time() 1733854833674 Apus@aos-2.0.1[Inbox:18]> Mint.mintBackUp({Timestamp = 1733854833674}) Not cool down yet
IsTNComing = IsTNComing or false
-
Variant Return variant of the token.
Apus@aos-2.0.1[Inbox:18]> Variant 0.0.3 -
Denomination Return denomination of the token.
Apus@aos-2.0.1[Inbox:18]> Denomination 12 -
Balances Return the balances of the token.
Apus@aos-2.0.1[Inbox:18]> Balances { JyQiTvqKIXZczY57PWOnhELUBIIKc56xWAbcM2_MXrk = "173634843142989879", lpJ5Edz_8DbNnVDL0XdbsY9vCOs45NACzfI4jvo4Ba8 = "340817915426344622", YB6KR9AdVCiOOJFRyHSBFxkgyMD-WOaN0AC6LTQ1MMQ = "80000000000000000000" }
-
TotalSupply Return the total supply of the token.
Apus@aos-2.0.1[Inbox:18]> TotalSupply 1000000000000000000000 -
Name Return the name of the token.
Apus@aos-2.0.1[Inbox:18]> Name Apus -
Ticker Return the ticker of the token.
Apus@aos-2.0.1[Inbox:18]> Ticker Apus -
Logo Return the logo address(ao address) of the token.
Apus@aos-2.0.1[Inbox:18]> Logo SBCCXwwecBlDqRLUjb8dYABExTJXLieawf7m2aBJ-KY -
IsTNComing Return if TN has coming.
Apus@aos-2.0.1[Inbox:18]> IsTNComing # no return value because it is false Apus@aos-2.0.1[Inbox:18]>
-
Token.info(msg) Return the info of token.
Apus@aos-2.0.1[Inbox:19]> Token.info({From = ao.id}) Return Info New Message From YB6...MMQ: Action = Info-Response Apus@aos-2.0.1[Inbox:20]> Inbox[20].Tags { Data-Protocol = "ao", Denomination = "12", Action = "Info-Response", Logo = "SBCCXwwecBlDqRLUjb8dYABExTJXLieawf7m2aBJ-KY", Variant = "ao.TN.1", Name = "Apus", Type = "Message", Pushed-For = "kuYtSWDRf7rkqwaklbd8mQjBmxYJbK3lyiazs12Oxxc", From-Module = "GuzQrkf50rBUqz3uUgjOIFOL1XmW9nSNysTBC-wyiWM", Reference = "4291", From-Process = "YB6KR9AdVCiOOJFRyHSBFxkgyMD-WOaN0AC6LTQ1MMQ", Ticker = "Apus" }
-
Token.balance(msg) Return the balance of target user.
# check balances Apus@aos-2.0.1[Inbox:20]> Balances { JyQiTvqKIXZczY57PWOnhELUBIIKc56xWAbcM2_MXrk = "174825370677781914", lpJ5Edz_8DbNnVDL0XdbsY9vCOs45NACzfI4jvo4Ba8 = "343198970495928692", YB6KR9AdVCiOOJFRyHSBFxkgyMD-WOaN0AC6LTQ1MMQ = "80000000000000000000" } Apus@aos-2.0.1[Inbox:20]> Token.balance({Tags = {Recipient = "JyQiTvqKIXZczY57PWOnhELUBIIKc56xWAbcM2_MXrk"}, From = ao.id}) New Message From YB6...MMQ: Data = 174825370677781914 Apus@aos-2.0.1[Inbox:21]> Inbox[21].Data 174825370677781914 Apus@aos-2.0.1[Inbox:21]> Token.balance({Tags = {Target = "lpJ5Edz_8DbNnVDL0XdbsY9vCOs45NACzfI4jvo4Ba8"}, From = ao.id}) New Message From YB6...MMQ: Data = 343198970495928692 Apus@aos-2.0.1[Inbox:22]> Inbox[22].Data 343198970495928692 Apus@aos-2.0.1[Inbox:22]> Token.balance({From = ao.id, Tags = {}}) New Message From YB6...MMQ: Data = 80000000000000000000 Apus@aos-2.0.1[Inbox:23]> Inbox[23].Data 80000000000000000000
-
Token.balances(msg) Return the balances. It is forbidden.
Apus@aos-2.0.1[Inbox:23]> Token.balances({From = ao.id}) New Message From YB6...MMQ: Data = {} Apus@aos-2.0.1[Inbox:24]> Inbox[24].Tags { Data-Protocol = "ao", From-Module = "GuzQrkf50rBUqz3uUgjOIFOL1XmW9nSNysTBC-wyiWM", Type = "Message", Note = "Feature disabled", Pushed-For = "pOnN6B0nx56OlY_fD1Rx1_Y06Lj4M8Ti2lS62-70YcM", Reference = "4300", From-Process = "YB6KR9AdVCiOOJFRyHSBFxkgyMD-WOaN0AC6LTQ1MMQ", Variant = "ao.TN.1" }
-
Token.transfer(msg) Transfer the apus token.
Apus@aos-2.0.1[Inbox:24]> Token.transfer({Recipient = "target", Quantity = "1000000", From = ao.id}) [string "aos"]:489: Cannot transfer until TN New Message From YB6...MMQ: Data = [string "aos"]:489:
-
Token.totalSupply(msg) Get the total supply of the token.
Apus@aos-2.0.1[Inbox:25]> Token.totalSupply({From = ao.id}) Error on line 562: error: Cannot call Total-Supply from the same process! This error occurred while aos was evaluating the submitted code.
-
Token.mintedSupply(msg) Get the minted supply.
Apus@aos-2.0.1[Inbox:25]> Token.mintedSupply({From = ao.id, reply = function() end})
-
Token.burn(msg) Burn the token.
Apus@aos-2.0.1[Inbox:26]> Token.burn({Quantity = "10000", From = ao.id}) Error on line 567: error: Cannot burn until TN