Protocol Mechanisms
Poll Creation
Poll Proposal Submission
The process initiates with the Poll Proposer, an individual or entity within the Tanθ network, who submits a new poll proposal. This proposal outlines the details of a decision or question that requires input from the community.
Governance Review
Upon submission, the poll proposal enters the Poll Review stage. This stage is managed by the governance body, which is responsible for scrutinizing the proposal to ensure it aligns with the community's standards and objectives. 2. The review process involves a thorough evaluation of the proposed poll including :
- Credibility of the source of truth
- Unambiguous resolution process
- Legal review (to exclude polls around terrorism, drugs etc)
Poll Approval
Following a successful review, the proposal proceeds to the Poll Approval stage. The governance body formally approves the poll, signifying its readiness for community interaction.
Dual Outcome Tokenizer (DOT)
- Token Minting
Approval of the poll triggers the minting of tokens:- A total of 100 million YES tokens are created, symbolizing affirmative responses to the poll.
- Similarly, 100 million NO tokens are minted, representing negative responses to the poll.
- Transfer to Reserve Predicate
The minted YES and NO tokens are then transferred to the Reserve Predicate. The Reserve Predicate functions as a secure vault and is used to perform swaps from USDT to Yes & No tokens.
Eg : When a user sends 1 USDT to the DOT, the DOT will send the user 1 YES and 1 NO tokens.
Deposit
Users can obtain packets by interacting with a smart contract that we call Packet Minter Contract. A Packet is a non-financial UTXO whose soul purpose is to allow for order cancellations.
Packet Minter Contract
The Packet Minter Contract is a straightforward contract that mints assets, assigning the sub-ID of the asset to the predicate address. The number of UTXOs minted corresponds to the number of simultaneous open orders an account can maintain.
Depositing to a Predicate
Users calculate the predicate address derived from the source code, with their signer address as a configurable. They then send assets - USDT & the Packet (obtained above) to this predicate as a deposit.
Order Flow
-
Order Creation:
-
User signs a message with the following attributes
fn sign_message(
asset_constraints: Vec<AssetConstraint>,
validity_utxo: b256,
authorized_solvers: Option<Vec<Address>>,
) -
Asset constraints: This is a list of constraints representing either the maximum spent or minimum received of an asset. Each element in this list includes an asset ID and a signed integer indicating the directional constraint of the asset (either the maximum spent or minimum received).
-
Packet (Validity UTXO): This is the UTXO ID, which is the hash of the transaction ID and output index. The specified UTXO must be included in the transaction to ensure its validity. This UTXO will have the asset ID generated by the Packet Minter Contract (described below).
-
Authorized solvers: This is an optional list of addresses authorized to act as the solver for this order. Any transaction that fulfills this order must include a signature from the solver, signing the entire transaction ID.
-
-
Order Communication:
- On-chain Logging - Logging the signature on-chain. This requires the user to pay gas fee. However this decentralized method of communicating orders has the least trust assumptions.
- Sending to Authorized Solver - Users can choose to send their orders directly to a solver without having to pay any gas fees. The user will have to trust the solver to be fair with the order matching.
-
Order Matching:
-
A solver will pick one or multiple orders on-chain, and construct a transaction to fill these orders (optionally filling them against their own assets).
-
Every input that’s included from the predicate must be validated by the predicate code, which accepts the following parameters:
fn main(
asset_constraints: Vec<AssetConstraint>,
order_witness_idx: u16,
authorized_solvers: Option<Vec<Address>>,
solver_witness_idx: Option<u16>,
) -> bool- Asset constraints: the same constraints signed in the order message..
- Order witness index: the pointer to the witness field containing the signature of the order.
- Authorized solvers: the list of authorized solvers included in the order.
- Solver witness ID: optional pointer to the witness field containing the signature from the solver (if the predicate requires authorized solvers).
-
The predicate will follow the following logic to validate the predicate:
- If the predicate requires an authorized solver, it will recover the signer of the solver signature from the witness, then iterate over the authorized solvers list to ensure the transaction was signed by this solver.
- Calculate the asset ID of the validity UTXO.
- Iterate over all inputs.
- If the input has the asset ID of the validity UTXO, notate the UTXO ID for order verification.
- If the input is owned by the predicate, add up the total amount of all assets spent.
- Iterate over all outputs
- If the output is owned by the predicate, subtract it from the total amount of assets spent.
- Ensure that the aggregated amounts of assets spent & received fits within the provided constraints.
- Reconstruct the order input and validate the order signature.
-
-
Order Cancellation
Depending on the mode of order communication, users can cancel their orders through the following mechanisms:
- Direct Communication to an Authorized Solver: Users can send a cancellation request to the solver via an API. This requires trust that the solver will not submit the canceled transaction.
- On-Chain Logging: Users can cancel an order by creating a transaction that consumes the Packet and outputs it to the same address, effectively invalidating the order.
Order-Matching Solver
A service will maintain a list of open orders in an off-chain database. Orders can be discovered through a centralized API or listening to the orders logged on-chain.
The solver will select orders from this list, match them against each other and form transactions to settle on-chain. The solver can also act as a market maker and fill orders against itself.
The solver pays the ETH gas fees for the transaction and is compensated by taking a fee from the spread between the inputs and outputs of the aggregated order set.
Market Orders
The service maintaining the list of open orders (off-chain database) sorts them in descending order. When a market order is received, the solver matches it with the top-most order in this list.
Withdrawal
Users can withdraw their funds from the predicate by signing an order that authorizes the spending of all their funds and designating themselves as the authorized solver.
Result Declaration
Poll / Event Lifecycle
- Proposal: Event is proposed.
- Approval: Event passes governance.
- Trading Starts: Frontends list the event for trading.
- Cancellation: Event can be canceled in some scenarios, such as a football match getting abandoned. In this case, both YES holders and NO holders are refunded their money.
- Expiry: Each event has an expiry time at which trading stops. Post expiry, the oracle updates the results.
- Outcome before Expiry: Some events can be resolved before their expiry. For example, "Will Binance list the Fuel token by the end of 2024?" (Expiry: 31st Dec 2024 11:59 PM) can be resolved to YES before its expiry.
Fund Movement
- Once the event enters the Finalized Phase (Cancellation, Expiry, or Outcome), the oracle announces the result.
- The oracle calculates the redemption predicate address derived from the source code, with the winning side (YES token / NO token) as a configurable.
- USDT is transferred from the reserve predicate to the redemption predicate.
- The YES / NO tokens in the user predicate can be swapped with USDT in the redemption predicate.