Links

Smart Contracts

The eckoDAO is a bespoke system comprised of a pair of smart contracts that interact with each other to accomplish different tasks related to governance. These are referred to as 'The Librarian' and 'The Lexicon'.

KDX-DAO (The Librarian
👵
)

The primary smart contract that handles Proposals is called the Librarian. This contract is designed to take care of proposals creation and management as well as keep track of votes for each specific proposal and account. The main features of the DAO contract are the following:
  • Create proposal and insert into proposals-table
  • Vote proposal by a specific account and insert into votes-table
  • Give information about proposals and actions taken by an account

Governance

The contract is governed by a keyset, "kaddex-ns-admin"

Operations

The contract operations are allowed to a keyset, "kaddex-ns-ops"

Tables

The contract contains 2 tables with following schema:
  • proposals-table: id title description account tot-approved tot-refused start-date end-date creation-date
  • votes-table: proposal-id account vp action

Functions

create-proposal

  • Creates proposal with the parameters: title description owner-account start-date end-date
  • Inserts the proposal into proposals-table
(create-proposal "New proposal" "this is a proposal" "k:govaddress" (time "2022-03-10T23:59:00Z") (time "2022-03-20T23:59:00Z"))

vote-proposal-helper

  • Takes three parameters: proposal-id account action
  • Inserts into votes-table the action (approved or refused) taken from an account on a specific proposal
(vote-proposal-helper "proposal-id" "k:bobaddress" "approved")

approved-vote

  • Takes proposal-id and account as parameters
  • calls vote-proposal-helper to vote for a proposal as approved
(approved-vote "proposal-id" "k:bobaddress")

refused-vote

  • Takes proposal-id and account as parameters
  • calls vote-proposal-helper to vote for a proposal as refused
(refused-vote "proposal-id" "k:bobaddress")

get-account-data

  • This function needs an account as a required argument and retuns the voting-power, multiplier and staked-amount of that specific account
  • These info are received from the aggregator contract
(get-account-data "k:bobaddress")

read-proposal

  • Get proposal info giving a specific proposal-id as argument
(read-proposal "proposal-id")

read-all-proposals

  • Get all proposals info
(read-all-proposals)

check-account-voted

  • This function takes an account and a proposal-id as arguments.
  • Checks if an account has already voted a specific proposal.
(check-account-voted "k:bobaddress" "proposal-id")

read-account-votes

  • Takes account as paramenter
  • Get vote info for each proposal that account has voted in the votes-table
(read-account-votes "k:bobaddress")

read-account-vote-proposal

  • Takes account and proposal-id as paramenter
  • Get vote info of account on specific proposal
(read-account-votes "prposal-id" "k:bobaddress")

The eckoDEX Aggregator (The Lexicon
📜
)

This contract is designed to manage each account's Voting Power. Voting Power (VP) is essential for a user that wants to vote a proposal in the DAO. Every time an account vote a proposal, the DAO contract make a call to the Aggregator contract in order to evaluate the VP of that specific account.

Governance

The contract is governed by a keyset, "kaddex-ns-admin"

Operations

The contract operations are allowed to a keyset, "kaddex-ns-ops"

Tables

The contract contains 2 tables with following schema:
  • staking-aggregator-table: account start-time staked-amount shift
  • privilege-table: guards action

Functions

grant-privilege

  • Takes a guard and an action as arguments.
  • This function grants a guard privilege to perform a specific action. If a guard does not have permission, the action won't be executed.
(grant-privilege (read-keyset 'guardaddress ) "aggregate-stake")

insert-lockup-batch

  • Takes a list of objects as argument.
  • Vaulting data are inserted into staking-aggregator-table through the use of this function. For a single user, the amount of kdx-locked coming from the vaulting program will be added up with the kdx-amount staked in order to create the Position of that specific user.
(insert-lockup-batch [{"account":"k:bobaddress", "amount": 100.0}])

aggregate-stake

  • Takes two parameters: requesting-account amount
  • It's called every time a new action of staking is made by an account. It is up to this function to verify whether an account is entering staking for the first time or not, if not, it checks if there is some amount already staked. Based on this information one of the three functions create-new-stake-row / update-account-entering-staking-again / update-old-stake-row is called to insert staking info into the staking-aggregator-table .
(aggregate-stake "k:bobaddress" 100.0)

aggregate-unstake

  • Takes two parameters: requesting-account unstaked-amount
  • It's called every time a new action of unstaking is made by an account. It is up to this function to call the update-when-unstaking function in order to update the staking-aggregator-table with the unstaking info.
(aggregate-unstake "k:bobaddress" 100.0)

get-voting-power

  • Receiving an account as argument, it returns the VP of that specific account.
(get-voting-power "k:bobaddress")

get-account-data

  • Takes an account as parameter.
  • This function returns an object containing info about the inserted account. In particular the outcome will be the Position, VP and Multiplier of the account.
(get-account-data "k:bobaddress")

read-all-staking

  • Get all staking info
(read-all-staking)

Voting Power ( VP ) Calculation

The formula to calculate the VP is:
V=PMV = \sqrt{P \cdot M}
where:
  • P: is the account Position, KDX amount ( staked-amount + kdx-locked in Vaulting program)
  • M: is the multiplier
The Voting Power Multiplier is a time-dependent function of your KDX staking amount. After the initial action of staking, in 60 days the Multiplier value goes up to 1 and can reach 2.5 over the course of 4 years. Every time a new action of staking is made, the Multiplier is recalculated based on the prervious amount staked and the new inserted amount. In order to performe this kind of calculation the shift value is used and stored. The shift value shifts the curve along the x axis to accommodate adding stakes at different times.
Multiplier formula:
M = s • ([ X - shift ] ^ z) + c
where:
  • X: is the time passed since the staking started
  • s, z, c: are constants used to model the multiplier-curve efficiently

Example:

user1:
- entering staking at T(0) with 100 KDX
- after 60 days --> Multiplier = 1 and VP = 10 = Math.sqrt( 100 • 1 )
user2:
- entering staking at T(0) with 10 KDX
- adding 90 KDX after 30 days
- after 60 days --> Multiplier = 0.8158 and VP = 9.03 = Math.sqrt( 100 • 0.8158 )
As it is possible to notice, after a period of 60 days, user1 will have acquired more VP compared to user2. This is due to the fact that user2 have made a new action of staking during the 60 days period, this action leads to an adjustment of the shift value, therefore to a lower Multiplier and VP.