diff --git a/.github/workflows/pull-docs.yml b/.github/workflows/pull-docs.yml index 15fc72e..6840062 100644 --- a/.github/workflows/pull-docs.yml +++ b/.github/workflows/pull-docs.yml @@ -1,29 +1,60 @@ -name: Pull README.md from the ixo-blockchain repository - -on: - pull_request_review_comment: - branches: - - develop +name: Copy docs from other repositories. +run-name: ${{ github.actor }} pushed a change. +on: [push] jobs: - pull-readme: + copy-docs-from-other-repos: runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 + - name: Checkout + uses: actions/checkout@v4 + with: + ref: alwyn-ixopatch-2 + + - name: Checkout ixo-blockchain + uses: actions/checkout@v4 + with: + repository: ixofoundation/ixo-blockchain + ref: develop + path: ixo-blockchain + + - name: Checkout ixo-signx + uses: actions/checkout@v4 + with: + repository: ixofoundation/ixo-signx + ref: main + path: ixo-signx + + - name: Checkout ixo-message-relayer + uses: actions/checkout@v4 + with: + repository: ixofoundation/ixo-message-relayer + ref: main + path: ixo-message-relayer - - name: Get *.md files from the ixo-blockchain repository - run: | - curl -O https://raw.githubusercontent.com/ixofoundation/ixo-blocksync/develop/**/*.md + - run: mkdir -p ./developers/ixo-blockchain/bonds + - run: mkdir -p ./developers/ixo-blockchain/claims + - run: mkdir -p ./developers/ixo-blockchain/entity + - run: mkdir -p ./developers/ixo-blockchain/iid + - run: mkdir -p ./developers/ixo-blockchain/token - - name: Move README.md to destination - run: | - mv *.md developers/ixo-blockchain + - run: cp -R ./ixo-blockchain/x/bonds/spec ./developers/ixo-blockchain/bonds + - run: cp -R ./ixo-blockchain/x/claims/spec ./developers/ixo-blockchain/claims + - run: cp -R ./ixo-blockchain/x/entity/spec ./developers/ixo-blockchain/entity + - run: cp -R ./ixo-blockchain/x/iid/spec ./developers/ixo-blockchain/iid + - run: cp -R ./ixo-blockchain/x/token/spec ./developers/ixo-blockchain/token + + - run: mkdir -p ./developers/ixo-signx + - run: find ./ixo-signx -type f -name "*.md" -exec cp -R {} ./developers/ixo-signx \; + + - run: mkdir -p ./developers/ixo-message-relayer + - run: find ./ixo-message-relayer -type f -name "*.md" -exec cp -R {} ./developers/ixo-message-relayer \; - - name: Create PR - uses: actions/create-pull-request@v4 - with: - title: "Pull .md files from ixo-block" - body: "This PR pulls the .md files from my-other-repo into the docs directory." - branch: "${{GITHUB_BRANCH}}" - base: develop - files: developers/ixo-blockchain/**/*.md + - run: rm -R ./ixo-blockchain + - run: rm -R ./ixo-signx + - run: rm -R ./ixo-message-relayer + + - run: git add . + - run: git config --global user.email "ixo@ixo.world" + - run: git config --global user.name ${{ github.actor }} + - run: git commit -m "Copy *.md files from other repos" + - run: git push origin alwyn-ixopatch-2 diff --git a/developers/ixo-blockchain/README.md b/developers/ixo-blockchain/README.md deleted file mode 100644 index e69de29..0000000 diff --git a/developers/ixo-blockchain/bonds/spec/01_concepts.md b/developers/ixo-blockchain/bonds/spec/01_concepts.md new file mode 100644 index 0000000..3497108 --- /dev/null +++ b/developers/ixo-blockchain/bonds/spec/01_concepts.md @@ -0,0 +1,115 @@ +# Concepts + +## Token Bonding Curves + +Bonding curves are continuous liquidity mechanisms which are used in market design for cryptographically-supported token economies. Tokens are atomic units of state information which are cryptographically verifiable in peer-to-peer networks. Bonding curves are an example of an enforceable mechanism through which participating agents influence this state. By designing such mechanisms, an engineer may establish the topological structure of a token economy without presupposing the utilities or associated actions of the agents within that economy. + +Token Bonding Curves are therefore an important crypto-economic mechanism for building a wide range of capabilities directly into decentralised applications. They can function simultaneously as means of decentralised capital formation, liquidity provision and autonomous market maker. +Bonding curves are powerful tools because the tokens they issue can represent rights - including + +- rights of access +- rights of use +- rights of ownership, and +- voting rights. + +In the case of continuous organizations, tokens issued through bonding curves embody rights to the future revenues of a startup. +In the augmented bonding curve, tokens can embody the rights to govern how funds are spent by a not-for-profit organization. +In an Alpha-Bond, tokens can give holders the rights to future outcomes payments and performance incentive bonuses. + +## Token Bonds Module + +The Token Bonds Cosmos SDK Module enables applications that use token bonding curves to be created on-the-fly. +Each new Token B instance declares a new token denomination in the application, with a set of parameters. +The module stores the current state of all tokens that have been created using this module. +Changes in state occur through transactions that are instructed by valid _buy, sell, and swap_ messages. + +**Buy** instructions cause bond tokens to be minted during a state transition. This increases the total supply balance of tokens. +**Sell** instructions burn bond tokens during a state transition that decreases the total supply balance of tokens. +**Limits** are set for the maximum numbers of bond tokens that can exist at any point in state. + +Bond Tokens trade against pairings in their Bond Reserve. + +The bonding curve forms an interface between the reserve token quantity and the bond token price (in the Reserve currency). + +Bonding curves are defined by their mathematical properties. This is determined by the type of curve function and by the function parameters that are set. Generally these parameters are chosen to best-fit empiricially-observed market dynamics of supply and demand. +External parameters, such as market supply and demand, are complex and typically hard to predict. + +--- + +Pricing is defined by the function type and function parameters, which can define either the pricing function of the bond as a function of the supply, or simply indicate that the bond is a token swapper, where pricing is instead defined by the first buyer and any swaps performed thereafter. + +A bond may also specify non-zero fees, which are calculated based on the size of an order and sent to the specified fee address, order quantity limits to limit the size of orders, disable the ability to sell tokens, specify multiple signers that will need to sign for any editing of the bond details, and in the case of swapper bonds, sanity values to set a range of valid exchange rate between the two reserve tokens. Lastly, a bond has a string state value, which in most cases is OPEN, but in certain function types it has more meaning, such as for augmented bonding curves, in which case it can be OPEN \[for open phase\] and HATCH \[for hatch phase\]. This state is _not_ specified by the creator during bond creation. + +```go +type Bond struct { + Token string + Name string + Description string + CreatorDid string + ControllerDid string + FunctionType string + FunctionParameters FunctionParams + ReserveTokens []string + TxFeePercentage sdk.Dec + ExitFeePercentage sdk.Dec + FeeAddress string + ReserveWithdrawalAddress string + MaxSupply sdk.Coin + OrderQuantityLimits sdk.Coins + SanityRate sdk.Dec + SanityMarginPercentage sdk.Dec + CurrentSupply sdk.Coin + CurrentReserve sdk.Coins + AvailableReserve sdk.Coins + CurrentOutcomePaymentReserve sdk.Coins + AllowSells bool + AllowReserveWithdrawals bool + AlphaBond bool + BatchBlocks sdk.Uint + OutcomePayment sdk.Int + State string + BondDid string +} +``` + +The following is a list of all possible bond states: + +- `"HATCH"` +- `"OPEN"` +- `"SETTLED"` +- `"FAILED"` + +By default, a newly created bond will be in state OPEN, unless the bond is an augmented bonding curve, in which case the initial state is HATCH. +The following are the valid transitions between bond states. + +
+- HATCH -> OPEN or FAILED +- OPEN -> SETTLE or FAILED ++ +No valid transitions exist from the SETTLE and FAILED states. + +## Batching + +For each bond, a single corresponding batch holds a collection of outstanding buy, sell, and swap orders. The lifespan of a batch, in terms of the number of blocks, is defined in the corresponding bond (`BatchBlocks`). + +Orders can be added to the current batch at any point in time. Any order that is not cancelled by the end of the batch's lifespan is eligible to get fulfilled. Otherwise, the order is discarded and any actions that were already performed are reverted. + +The primary task of the batching mechanism is to find a common price for all of the buys and sells submitted to the batch by summing up all of the buys and sells, thus ignoring their order, and matching-up the total buy and sell amounts to give balanced and fair global buy and sell prices. + +For alpha bonds, the batch also stores the next alpha value, if it was changed throughout the lifetime of the batch. If alpha has not changed, then it will show up as `-1`. + +```go +type Batch struct { + BondDid string + BlocksRemaining sdk.Uint + NextPublicAlpha sdk.Dec + TotalBuyAmount sdk.Coin + TotalSellAmount sdk.Coin + BuyPrices sdk.DecCoins + SellPrices sdk.DecCoins + Buys []BuyOrder + Sells []SellOrder + Swaps []SwapOrder +} +``` diff --git a/developers/ixo-blockchain/bonds/spec/02_state.md b/developers/ixo-blockchain/bonds/spec/02_state.md new file mode 100644 index 0000000..6c7db06 --- /dev/null +++ b/developers/ixo-blockchain/bonds/spec/02_state.md @@ -0,0 +1,22 @@ +# State + +## Bonds + +The instance of a bond is stored with its bond-specific parameters. This record is accessed by the identity of a token that represents the bond. + +- Bonds: `0x00 | tokenHash -> ProtocolBuffer(Bond)` + +## Batches + +As a protection against front-runnning orders, a batching mechanism creates a cache of orders and combines these into a single transaction when the batch conditions have been met. +The state of 2 consecutive batches is held for both the current and last (previous) batch. +This enables querying the final state of a batch before the orders were fulfilled, after the transaction has completed. +The temporary state of a batch in the current block is not observable. This batch is cleared as soon as the batch transaction has completed. + +### Querying Batches + +Batches are accessed by the identity token of the bond. + +- Current Batches: `0x01 | bondDid -> ProtocolBuffer(Batch) ` + +- Last Batches: `0x02 | bondDid -> ProtocolBuffer(Batch) ` diff --git a/developers/ixo-blockchain/bonds/spec/03_messages.md b/developers/ixo-blockchain/bonds/spec/03_messages.md new file mode 100644 index 0000000..3416e48 --- /dev/null +++ b/developers/ixo-blockchain/bonds/spec/03_messages.md @@ -0,0 +1,391 @@ +# Messages + +In this section we describe the processing of the bonds messages and the corresponding updates to the state. All created/modified state objects specified by each message are defined within the [state](./02_state.md) section. + +## MsgCreateBond + +Bonds can be created by any address using `MsgCreateBond`. + +| **Field** | **Type** | **Description** | +| :----------------------- | :--------------- | :------------------------------------------------------------------------------------------------------------------------ | +| BondDid | `did.Did` | DID of the bond (e.g. `did:ixo:U7GK8p8rVhJMKhBVRCJJ8c`) | +| Token | `string` | The denomination of the bond's tokens (e.g. `abc`, `mytoken1`) | +| Name | `string` | A friendly name as a title for the bond (e.g. `A B C`, `My Token`) | +| Description | `string` | A description of what the bond represents or its purpose | +| FunctionType | `string` | The type of function that will define the bonding curve (`power_function`, `sigmoid_function`, or `swapper_function`) | +| FunctionParameters | `FunctionParams` | The parameters of the function defining the bonding curve (e.g. `m:12,n:2,c:100`) | +| CreatorDid | `did.Did` | DID of the bond creator (e.g. `did:ixo:U7GK8p8rVhJMKhBVRCJJ8c`) | +| ControllerDid | `did.Did` | DID of the bond controller (e.g. `did:ixo:U7GK8p8rVhJMKhBVRCJJ8c`) | +| ReserveTokens | `[]string` | The token denominations that will be used as reserve (e.g. `res,rez`) | +| TxFeePercentage | `sdk.Dec` | The percentage fee charged for buys/sells/swaps (e.g. `0.3`) | +| ExitFeePercentage | `sdk.Dec` | The percentage fee charged for sells on top of the tx fee (e.g. `0.2`) | +| FeeAddress | `sdk.AccAddress` | The address of the account that will store charged fees | +| ReserveWithdrawalAddress | `sdk.AccAddress` | The address of the account that will receive any reserve withdrawn by the controller | +| MaxSupply | `sdk.Coin` | The maximum number of bond tokens that can be minted | +| OrderQuantityLimits | `sdk.Coins` | The maximum number of tokens that one can buy/sell/swap in a single order (e.g. `100abc,200res,300rez`) | +| SanityRate | `sdk.Dec` | For a swapper, restricts conversion rate (`r1/r2`) to `sanity rate ยฑ sanity margin percentage`. `0` for no sanity checks. | +| SanityMarginPercentage | `sdk.Dec` | Used as described above. `0` for no sanity checks | +| AllowSells | `bool` | Whether or not selling is allowed (cannot be True if AllowReserveWithdrawals is True) | +| AllowReserveWithdrawals | `bool` | Whether or not reserve withdrawals are allowed (cannot be True if AllowSells is True) | +| AlphaBond | `bool` | Whether or not bond is an alpha bond | +| BatchBlocks | `sdk.Uint` | The lifespan of each orders batch in blocks | +| OutcomePayment | `sdk.Int` | The approximate total payment required to be made in order to transition a bond from OPEN to SETTLE | + +```go +type MsgCreateBond struct { + BondDid string + Token string + Name string + Description string + FunctionType string + FunctionParameters FunctionParams + CreatorDid string + ControllerDid string + ReserveTokens []string + TxFeePercentage sdk.Dec + ExitFeePercentage sdk.Dec + FeeAddress string + ReserveWithdrawalAddress string + MaxSupply sdk.Coin + OrderQuantityLimits sdk.Coins + SanityRate sdk.Dec + SanityMarginPercentage sdk.Dec + AllowSells bool + AllowReserveWithdrawals bool + AlphaBond bool + BatchBlocks sdk.Uint + OutcomePayment sdk.Int +} +``` + +This message is expected to fail if: + +- another bond with this bond DID is already registered +- another bond with this token is already registered, the token is the staking token, or the token is not a valid denomination +- name or description is an empty string +- function type is not one of the defined function types (`power_function`, `sigmoid_function`, `swapper_function`, `augmented_function`) +- function parameters are negative or invalid for the selected function type: + - Valid example for `power_function`: `"m:12.5,n:2,c:100.12"` \ + (i.e. `m=12`, `n=2`, `n=100.12`) + - Valid example for `sigmoid_function`: `"a:3.5,b:5.4,c:1.3"` \ + (i.e. `a=3.5`, `b=5.4`, `c=1.3`) + - Valid example for `augmented_function`: `"d0:500.0,p0:0.01,theta:0.4,kappa:3.0"` \ + (i.e. `d0=500.0`, `p0=0.01`, `theta=0.4`, `kappa=3.0`) + - For `swapper_function`: `""` (no parameters) +- function parameters do not satisfy the extra parameter restrictions + - `sigmoid_function`: `c != 0` + - `augmented_function`: + - `d0 > 0` and must be an integer + - `p0 > 0` + - `0 <= theta < 1` + - `kappa > 0` +- bond DID, creator DID, or controller DID is not a valid DID +- reserve tokens list is invalid. Valid inputs are: + - For `swapper_function`: two valid comma-separated denominations, e.g. `res,rez` + - Otherwise: one or more valid comma-separated denominations, e.g. `res,rez,rex` +- tx or exit fee percentage is negative +- sum of tx and exit fee percentages exceeds 100% +- fee address or reserve withdrawal address are not valid +- order quantity limits is not one or more valid comma-separated amount + - Valid example: `"100res,200rez"` +- max supply value is not in the bond token denomination +- sanity rate is neither an empty string nor a valid decimal +- sanity margin percentage is neither an empty string nor a valid decimal +- sanity rate is not an empty string and sanity margin percentage is an empty string (in other words, sanity rate is defined but sanity margin percentage is not) +- outcome payment is not an integer or is negative +- any field is empty, except for order quantity limits, sanity rate, sanity margin percentage, and function parameters for `swapper_function` +- both AllowSells and AllowReserveWithdrawals are True + +This message creates and stores the `Bond` object at appropriate indexes. Note that the sanity rate and sanity margin percentage are only used in the case of the `swapper_function`, but no error is raised if these are set for other function types. + +## MsgEditBond + +The owner of a bond can edit some of the bond's parameters using `MsgEditBond`. + +| **Field** | **Type** | **Description** | +| :--------------------- | :-------- | :------------------------------------------------------------------------------ | +| BondDid | `did.Did` | DID of the bond we are interacting with (e.g. `did:ixo:U7GK8p8rVhJMKhBVRCJJ8c`) | +| Name | `string` | Refer to MsgCreateBond | +| Description | `string` | Refer to MsgCreateBond | +| OrderQuantityLimits | `string` | Refer to MsgCreateBond | +| SanityRate | `string` | Refer to MsgCreateBond | +| SanityMarginPercentage | `string` | Refer to MsgCreateBond | +| EditorDid | `did.Did` | DID of the bond editor (e.g. `did:ixo:U7GK8p8rVhJMKhBVRCJJ8c`) | + +This message is expected to fail if: + +- bond does not exist +- any editable field violates the restrictions set for the same field in `MsgCreateBond` +- all editable fields are `"[do-not-modify]"` +- editor is not the bond creator +- bond DID or editor DID is not a valid DID + +```go +type MsgEditBond struct { + BondDid string + Name string + Description string + OrderQuantityLimits string + SanityRate string + SanityMarginPercentage string + EditorDid string +} +``` + +This message stores the updated `Bond` object. + +## MsgSetNextAlpha + +The controller of a bond can set the next public alpha value for Augmented Bonding Curve type bonds using `MsgSetNextAlpha`. + +| **Field** | **Type** | **Description** | +| :-------- | :-------- | :------------------------------------------------------------------------------ | +| BondDid | `did.Did` | DID of the bond we are interacting with (e.g. `did:ixo:U7GK8p8rVhJMKhBVRCJJ8c`) | +| Alpha | `sdk.Dec` | Public alpha value to be set (e.g. `0.5`) | +| EditorDid | `did.Did` | DID of the bond editor (e.g. `did:ixo:U7GK8p8rVhJMKhBVRCJJ8c`) | + +This message is expected to fail if: + +- bond does not exist +- public alpha value falls outside of 0.0001 <= alpha <= 0.9999 +- public alpha value violates any of the below rules + - `newPublicAlpha != publicAlpha` +- resultant system alpha value violates any of the below rules + - `newSystemAlpha != systemAlpha` + - `I > C * systemAlpha` + - `R / C > newSystemAlpha - systemAlpha` +- editor is not the bond controller +- bond DID or editor DID is not a valid DID + +```go +type MsgSetNextAlpha struct { + BondDid string + Alpha sdk.Dec + EditorDid string +} +``` + +This message stores the next alpha value in the current `Batch` object, where it gets processed and set at the end of the batch. + +## MsgUpdateBondState + +The controller of a bond can change a bond's state to SETTLE or FAILED using `MsgUpdateBondState`. + +| **Field** | **Type** | **Description** | +| :-------- | :---------- | :------------------------------------------------------------------------------ | +| BondDid | `did.Did` | DID of the bond we are interacting with (e.g. `did:ixo:U7GK8p8rVhJMKhBVRCJJ8c`) | +| State | `BondState` | Bond state to be set (e.g. `SETTLE`) | +| EditorDid | `did.Did` | DID of the bond editor (e.g. `did:ixo:U7GK8p8rVhJMKhBVRCJJ8c`) | + +This message is expected to fail if: + +- bond does not exist +- state is not SETTLE or FAILED +- state is not a valid transition from the current bond state +- editor is not the bond controller +- bond DID or editor DID is not a valid DID + +```go +type MsgUpdateBondState struct { + BondDid string + State string + EditorDid string +} +``` + +This message updates the bond status to SETTLE or FAILED and moves the outcome payment reserve to the bond reserve, so that this is available for bond token holders to withdraw a share from, proportional to the amount of bond tokens they hold. + +## MsgBuy + +Any address that holds tokens that a bond uses as its reserve can buy tokens from that bond in exchange for reserve tokens. Rather than performing the buy itself, the `MsgBuy` handler registers a buy order in the current orders batch and cancels any other orders that become unfulfillable. Any order in that batch gets fulfilled at the end of the batch's lifespan. The `MsgBuy` handler also locks away the `MaxPrices` value (`< Balance`) indicated by the address so that these are not used elsewhere whilst the batch is being processed. + +A buy order is cancelled if the max prices are exceeded at any point during the lifespan of the batch. Otherwise, the buy order is fulfilled. The number of tokens requested are minted on the fly and any remaining tokens from the locked `MaxPrices`, minus the transaction fee specified by the bond, are returned to the user. The actual price in reserve tokens charged to the address is determined from the bond function, but is also influenced by any other buys and sells in the same orders batch, as a means to prevent front-running. + +In the case of `augmented_function` bonds, if the bond state is `HATCH`, a fixed price-per-token `p0` is used. This value (`p0`) is one of the function parameters required for this function type. + +| **Field** | **Type** | **Description** | +| :-------- | :---------- | :------------------------------------------------------------------------------ | +| BuyerDid | `did.Did` | DID of the buyer (e.g. `did:ixo:U7GK8p8rVhJMKhBVRCJJ8c`) | +| Amount | `sdk.Coin` | The amount of bond tokens to be bought | +| MaxPrices | `sdk.Coins` | The max price to pay in reserve tokens | +| BondDid | `did.Did` | DID of the bond we are interacting with (e.g. `did:ixo:U7GK8p8rVhJMKhBVRCJJ8c`) | + +This message is expected to fail if: + +- bond does not exist or bond state is not HATCH or OPEN +- amount is not an amount of an existing bond +- max prices is greater than the balance of the buyer +- max prices are not amounts of the bond's reserve tokens +- denominations in max prices are not the bond's reserve tokens +- buyer does not afford to buy the tokens at the current price +- amount causes the bond's batch-adjusted current supply to exceed the max supply +- amount violates an order quantity limit defined by the bond +- bond DID or buyer DID is not a valid DID + +The batch-adjusted current supply in the case of buys is the current supply of the bond plus any uncancelled buy amounts in the current batch. + +```go +type MsgBuy struct { + BuyerDid string + Amount sdk.Coin + MaxPrices sdk.Coins + BondDid string +} +``` + +This message adds the buy order to the current batch. + +### MsgBuy for Swapper Function Bonds + +In general, but especially in the case of swapper function bonds, buying tokens from a bond can be seen as adding liquidity to that bond's token. To add liquidity to a swapper function, the current exchange rate is used to determine how much of each reserve token makes up the price. Otherwise, the price is an equal number of each of the reserve tokens according to the function type. + +Moreover, in the case of the swapper function, the first `MsgBuy` performed is special and plays a very important role in specifying the price of the bond token. Since we have no price reference for the first buy in a swapper function, the `MaxPrices` specified are used as the actual price, with no fees charged. + +This effectively means that if the user requested `n` bond tokens with max prices `aR1` and `bR2` (for reserve tokens `R1` and `R2`), the next buyers will have to pay `(a/n)R1` and `(b/n)R2` tokens per bond token requested. Specifying high `a` and `b` prices for a small `n` (say `n=1`) means that the next buyers will have to pay at most `aR1` and `bR2` per bond token. **Thus, it is important that the first buy is well-calculated and performed carefully.** + +## MsgSell + +Any address that holds previously bought bond tokens can, at any point, sell the tokens back to the bond in exchange for reserve tokens. Similar to the `MsgBuy`, the `MsgSell` handler just registers a sell order in the current orders batch which then gets fulfilled at the end of the batch's lifespan. + +Once the sell order is fulfilled, the number of tokens to be sold are burned on the fly and the address gets reserve tokens in return, minus the transaction and exit fees specified by the bond. The actual number of reserve tokens given to the address in return is determined from the bond function, but is also influenced by any other buys and sells in the same orders batch, as a means to prevent front-running. A sell order cannot be cancelled. + +In general, but especially in the case of swapper function bonds, buying tokens from a bond can be seen as adding liquidity for that bond. To add liquidity to a swapper function, the current exchange rate is used to determine how much of each reserve token makes up the price. Otherwise, the price is an equal number of each of the reserve tokens according to the function type. + +| **Field** | **Type** | **Description** | +| :-------- | :--------- | :------------------------------------------------------------------------------ | +| SellerDid | `did.Did` | DID of the seller (e.g. `did:ixo:U7GK8p8rVhJMKhBVRCJJ8c`) | +| Amount | `sdk.Coin` | The amount of bond tokens to be sold | +| BondDid | `did.Did` | DID of the bond we are interacting with (e.g. `did:ixo:U7GK8p8rVhJMKhBVRCJJ8c`) | + +This message is expected to fail if: + +- bond does not exist or bond state is not OPEN +- amount is not an amount of an existing bond +- amount is greater than the balance of the seller +- amount is greater than the bond's current supply +- amount causes the bond's batch-adjusted current supply to become negative +- amount violates an order quantity limit defined by the bond +- bond function type is `augmented_function` and bond state is `HATCH` +- bond DID or seller DID is not a valid DID + +The batch-adjusted current supply in the case of sells is the current supply of the bond minus any uncancelled sell amounts in the current batch. + +```go +type MsgSell struct { + SellerDid string + Amount sdk.Coin + BondDid string +} +``` + +This message adds the sell order to the current batch. + +## MsgSwap + +Any address that holds tokens (_t1_) that a swapper function bond uses as one of its two reserves (_t1_ and _t2_) can swap the tokens in exchange for reserve tokens of the other type (_t2_). Similar to the `MsgBuy` and `MsgSell`, the `MsgSwap` handler just registers a swap order in the current orders batch which then gets fulfilled at the end of the batch's lifespan. + +| **Field** | **Type** | **Description** | +| :--------- | :--------- | :------------------------------------------------------------------------------ | +| SwapperDid | `did.Did` | DID of the swapper (e.g. `did:ixo:U7GK8p8rVhJMKhBVRCJJ8c`) | +| BondDid | `did.Did` | DID of the bond we are interacting with (e.g. `did:ixo:U7GK8p8rVhJMKhBVRCJJ8c`) | +| From | `sdk.Coin` | The amount of reserve tokens to be swapped | +| ToToken | `string` | The token denomination that will be given in return | + +This message is expected to fail if: + +- bond does not exist, is not swapper function, or bond state is not OPEN +- from amount is greater than the balance of the swapper +- from and to tokens are the same token +- from and to tokens are not the swapper function's reserve tokens +- from amount violates an order quantity limit defined by the bond +- bond DID or swapper DID is not a valid DID + +```go +type MsgSwap struct { + SwapperDid string + BondDid string + From sdk.Coin + ToToken string +} +``` + +This message adds the swap order to the current batch. + +## MsgMakeOutcomePayment + +If a bond was created with an outcome payment field, then any token holder can make an outcome payment to the bond. If the token holder has enough tokens to pay the outcome payment, the tokens are sent to the bond's reserve and the bond's state gets set to SETTLE. The only action possible by bond token holders after the outcome payment has been made is a share withdrawal (using [MsgWithdrawShare](#MsgWithdrawShare)). + +| **Field** | **Type** | **Description** | +| :-------- | :-------- | :------------------------------------------------------------------------------ | +| SenderDid | `did.Did` | DID of the sender (e.g. `did:ixo:U7GK8p8rVhJMKhBVRCJJ8c`) | +| Amount | `sdk.Int` | Amount of payment sender is making (e.g. `100000`) | +| BondDid | `did.Did` | DID of the bond we are interacting with (e.g. `did:ixo:U7GK8p8rVhJMKhBVRCJJ8c`) | + +This message is expected to fail if: + +- bond does not exist or bond state is not OPEN +- bond outcome payment is zero or negative +- bond outcome payment is greater than the balance of the sender +- bond DID or sender DID is not a valid DID + +```go +type MsgMakeOutcomePayment struct { + SenderDid string + Amount sdk.Int + BondDid string +} +``` + +## MsgWithdrawShare + +If a bond's outcome payment was paid, any bond token holder can use this message to get their share of the reserve. The amount owed to the bond token holder is calculated by considering the percentage of bond tokens owned as a fraction of the _remaining_ bond token supply. Examples: + +- If the bond token holder owns 100% of all bond tokens and the reserve has 1000 reserve tokens, then the bond token holder gets all 1000 reserve tokens. +- If three bond token holders each own 1/3 of all bond tokens and the reserve has 1000 reserve tokens, then: + - The first token holder to withdraw gets `1000/3 = 333 tokens` (notice the rounding down from 333.33) + - The second token holder to withdraw gets `667/2 = 333 tokens` (notice the current supply is now 2) + - The third token holder to withdraw gets `334/1 = 334 tokens` (because of rounding, the last holder got an extra token) + +| **Field** | **Type** | **Description** | +| :----------- | :-------- | :------------------------------------------------------------------------------ | +| RecipientDid | `did.Did` | DID of the recipient (e.g. `did:ixo:U7GK8p8rVhJMKhBVRCJJ8c`) | +| BondDid | `did.Did` | DID of the bond we are interacting with (e.g. `did:ixo:U7GK8p8rVhJMKhBVRCJJ8c`) | + +This message is expected to fail if: + +- bond does not exist or bond state is not SETTLE +- recipient does not own any bond tokens +- bond DID or recipient DID is not a valid DID + +```go +type MsgWithdrawShare struct { + RecipientDid string + BondDid string +} +``` + +## MsgWithdrawReserve + +If the bond allows it, i.e. if the `AllowReserveWithdrawals` flag is set to True, then the bond's controller has the ability to withdraw reserve out of the bond's reserve, for usage outside of the bond. This will not affect the `CurrentReserve` reported by the bond but will update the `AvailableReserve` value. + +| **Field** | **Type** | **Description** | +| :------------ | :---------- | :------------------------------------------------------------------------------ | +| WithdrawerDid | `did.Did` | DID of the withdrawer (e.g. `did:ixo:U7GK8p8rVhJMKhBVRCJJ8c`) | +| Amount | `sdk.Coins` | The amount of reserve tokens to be withdrawn | +| BondDid | `did.Did` | DID of the bond we are interacting with (e.g. `did:ixo:U7GK8p8rVhJMKhBVRCJJ8c`) | + +This message is expected to fail if: + +- bond does not exist or bond state is not OPEN +- withdrawer is not the bond's controller +- bond DID or withdrawer DID is not a valid DID +- amount is not a valid amount +- bond does not have sufficient available reserve + +```go +type MsgWithdrawReserve struct { + WithdrawerDid string + Amount sdk.Coin + BondDid string +} +``` diff --git a/developers/ixo-blockchain/bonds/spec/04_end_block.md b/developers/ixo-blockchain/bonds/spec/04_end_block.md new file mode 100644 index 0000000..50a9da4 --- /dev/null +++ b/developers/ixo-blockchain/bonds/spec/04_end_block.md @@ -0,0 +1,58 @@ +# End-Block + +At the end of each block, any batch of orders that has reached the end of its lifespan, measured in number of blocks, is cleared. For the rest of the batches, their blocks remaining value is decremented by 1. Orders are performed in the following order: + +1. Buys +2. Sells +3. Swaps + +Since the buy and sell prices are pre-calculated from when the buy and sell orders were added to the batch, there is no additional cancellations of buys or sells that will take place at this stage. However, swaps are processed on a first come first served basis and a swap is cancelled if it violates the sanity rates. + +In the case of `augmented_function` bonds, if the new bond supply after performing all orders is greater or equal to the initial supply (`supply >= S0`), the bond's state gets updated from `HATCH` to `OPEN` and sells are enabled if `AllowSells == true`. + +## Buys + +Using the buy price stored in the batch, the following steps are followed for each buy order: + +1. Mint and send `n` bond tokens to the buyer +2. Calculate total price`total = r + f` in reserve tokens + 1. `r` is the price of buying `n` bond tokens + 2. `f` is the transactional fee based on `r` +3. Send `r` to the reserve +4. Send `f` to the fee address +5. Send unused reserve tokens (`maxPrices-total`) back to buyer +6. Increase bond's current supply by `n` + +Note: the `maxPrices` reserve tokens were locked upon submitting the buy order. + +## Sells + +Using the sell price stored in the batch, the following steps are followed for each sell order: + +1. Calculate total returns `total = r - f` in reserve tokens + 1. `r` is the return for selling `n` bond tokens + 2. `f` is the transactional and exit fees based on `r` +2. Send `total` to the seller +3. Send `f` to the fee address +4. Decrease bond's current supply by `n` + +Note: the `n` bond tokens were burned upon submitting the sell order. + +## Swaps + +The following steps are followed for each swap order: + +1. Calculate the transactional fee `f` based on `t1` reserve tokens +2. Calculate the return `t2` for swapping `t1-f` reserve tokens +3. Check whether the swap violates the sanity rate + 1. Calculate the new reserve balances as a result of the swap + 2. Cancel the swap if the new balances violate the sanity rate +4. Send `t2` to the swapper +5. Send `t1-f` to the reserve +6. Send `f` to the fee address + +Note: the `t1` reserve tokens were locked upon submitting the swap order. If a swap order is cancelled, the `t1` tokens are immediately returned back to the swapper. + +## Set Last Batch + +Once all orders have been processed, the last batch is set as the current batch and the current batch is cleared in preparation for a new list of orders. diff --git a/developers/ixo-blockchain/bonds/spec/05_events.md b/developers/ixo-blockchain/bonds/spec/05_events.md new file mode 100644 index 0000000..a289478 --- /dev/null +++ b/developers/ixo-blockchain/bonds/spec/05_events.md @@ -0,0 +1,285 @@ +# Events + +The bonds module emits the following typed events: + +### BondCreatedEvent + +Emitted after a successfull `MsgCreateBond` + +| **Field** | **Type** | **Description** | +| :-------- | :------- | :-------------- | +| Bond | `*Bond` | | + +```go +type BondCreatedEvent struct { + Bond *Bond +} +``` + +### BondUpdatedEvent + +Emitted after a successfull `MsgEditBond`, `MsgUpdateBondState` + +| **Field** | **Type** | **Description** | +| :-------- | :------- | :-------------- | +| Bond | `*Bond` | | + +```go +type BondUpdatedEvent struct { + Bond *Bond +} +``` + +### BondSetNextAlphaEvent + +Emitted after a successfull `MsgSetNextAlpha`. Note this doesn't mean the alpha has been updated, it has only been added to the batch for next batch update. + +| **Field** | **Type** | **Description** | +| :-------- | :------- | :-------------- | +| BondDid | `string` | | +| NextAlpha | `string` | | +| Signer | `string` | | + +```go +type BondSetNextAlphaEvent struct { + BondDid string + NextAlpha string + Signer string +} +``` + +### BondBuyOrderEvent + +Emitted after a successfull `MsgBuy`. Note this doesn't mean the buy has been executed, it has only been added to the batch. + +| **Field** | **Type** | **Description** | +| :-------- | :---------- | :-------------- | +| BondDid | `string` | | +| Order | `*BuyOrder` | | + +```go +type BondBuyOrderEvent struct { + Order *BuyOrder + BondDid string +} +``` + +### BondSellOrderEvent + +Emitted after a successfull `MsgSell`. Note this doesn't mean the sell has been executed, it has only been added to the batch. + +| **Field** | **Type** | **Description** | +| :-------- | :----------- | :-------------- | +| BondDid | `string` | | +| Order | `*SellOrder` | | + +```go +type BondSellOrderEvent struct { + Order *SellOrder + BondDid string +} +``` + +### BondSwapOrderEvent + +Emitted after a successfull `MsgSwap`. Note this doesn't mean the swap has been executed, it has only been added to the batch. + +| **Field** | **Type** | **Description** | +| :-------- | :----------- | :-------------- | +| BondDid | `string` | | +| Order | `*SwapOrder` | | + +```go +type BondSwapOrderEvent struct { + Order *SwapOrder + BondDid string +} +``` + +### BondMakeOutcomePaymentEvent + +Emitted after a successfull `MsgMakeOutcomePayment` + +| **Field** | **Type** | **Description** | +| :------------- | :----------------------------------------- | :-------------- | +| BondDid | `string` | | +| OutcomePayment | `github_com_cosmos_cosmos_sdk_types.Coins` | | +| SenderDid | `string` | | +| SenderAddress | `string` | | + +```go +type BondMakeOutcomePaymentEvent struct { + BondDid string + OutcomePayment github_com_cosmos_cosmos_sdk_types.Coins + SenderDid string + SenderAddress string +} +``` + +### BondWithdrawShareEvent + +Emitted after a successfull `MsgWithdrawShare` + +| **Field** | **Type** | **Description** | +| :--------------- | :----------------------------------------- | :-------------- | +| BondDid | `string` | | +| WithdrawPayment | `github_com_cosmos_cosmos_sdk_types.Coins` | | +| RecipientDid | `string` | | +| RecipientAddress | `string` | | + +```go +type BondWithdrawShareEvent struct { + BondDid string + WithdrawPayment github_com_cosmos_cosmos_sdk_types.Coins + RecipientDid string + RecipientAddress string +} +``` + +### BondWithdrawReserveEvent + +Emitted after a successfull `MsgWithdrawReserve` + +| **Field** | **Type** | **Description** | +| :----------------------- | :----------------------------------------- | :-------------- | +| BondDid | `string` | | +| WithdrawAmount | `github_com_cosmos_cosmos_sdk_types.Coins` | | +| WithdrawerDid | `string` | | +| WithdrawerAddress | `string` | | +| ReserveWithdrawalAddress | `string` | | + +```go +type BondWithdrawReserveEvent struct { + BondDid string + WithdrawAmount github_com_cosmos_cosmos_sdk_types.Coins + WithdrawerDid string + WithdrawerAddress string + ReserveWithdrawalAddress string +} +``` + +### BondEditAlphaSuccessEvent + +Emitted after a successfull update of the Alpha state which is done in `EndBlock` + +| **Field** | **Type** | **Description** | +| :---------- | :------- | :-------------- | +| BondDid | `string` | | +| Token | `string` | | +| PublicAlpha | `string` | | +| SystemAlpha | `string` | | + +```go +type BondEditAlphaSuccessEvent struct { + BondDid string + Token string + PublicAlpha string + SystemAlpha string +} +``` + +### BondEditAlphaFailedEvent + +Emitted if update of the Alpha state failed which is done in `EndBlock` + +| **Field** | **Type** | **Description** | +| :----------- | :------- | :-------------- | +| BondDid | `string` | | +| Token | `string` | | +| CancelReason | `string` | | + +```go +type BondEditAlphaFailedEvent struct { + BondDid string + Token string + CancelReason string +} +``` + +### BondBuyOrderFulfilledEvent + +Emitted after a successfull `BuyOrder` has been executed which is done in `EndBlock` + +| **Field** | **Type** | **Description** | +| :-------------------------- | :----------------------------------------- | :-------------- | +| BondDid | `string` | | +| Order | `*BuyOrder` | | +| ChargedPrices | `github_com_cosmos_cosmos_sdk_types.Coins` | | +| ChargedFees | `github_com_cosmos_cosmos_sdk_types.Coins` | | +| ReturnedToAddress | `github_com_cosmos_cosmos_sdk_types.Coins` | | +| NewBondTokenBalance | `github_com_cosmos_cosmos_sdk_types.Int` | | +| ChargedPricesOfWhichReserve | `*github_com_cosmos_cosmos_sdk_types.Int` | | +| ChargedPricesOfWhichFunding | `github_com_cosmos_cosmos_sdk_types.Coins` | | + +```go +type BondBuyOrderFulfilledEvent struct { + BondDid string + Order *BuyOrder + ChargedPrices github_com_cosmos_cosmos_sdk_types.Coins + ChargedFees github_com_cosmos_cosmos_sdk_types.Coins + ReturnedToAddress github_com_cosmos_cosmos_sdk_types.Coins + NewBondTokenBalance github_com_cosmos_cosmos_sdk_types.Int + ChargedPricesOfWhichReserve *github_com_cosmos_cosmos_sdk_types.Int + ChargedPricesOfWhichFunding github_com_cosmos_cosmos_sdk_types.Coins +} +``` + +### BondSellOrderFulfilledEvent + +Emitted after a successfull `SellOrder` has been executed which is done in `EndBlock` + +| **Field** | **Type** | **Description** | +| :------------------ | :----------------------------------------- | :-------------- | +| BondDid | `string` | | +| Order | `*SellOrder` | | +| ChargedFees | `github_com_cosmos_cosmos_sdk_types.Coins` | | +| ReturnedToAddress | `github_com_cosmos_cosmos_sdk_types.Coins` | | +| NewBondTokenBalance | `github_com_cosmos_cosmos_sdk_types.Int` | | + +```go +type BondSellOrderFulfilledEvent struct { + BondDid string + Order *SellOrder + ChargedFees github_com_cosmos_cosmos_sdk_types.Coins + ReturnedToAddress github_com_cosmos_cosmos_sdk_types.Coins + NewBondTokenBalance github_com_cosmos_cosmos_sdk_types.Int +} +``` + +### BondSwapOrderFulfilledEvent + +Emitted after a successfull `SwapOrder` has been executed which is done in `EndBlock` + +| **Field** | **Type** | **Description** | +| :---------------- | :----------------------------------------- | :-------------- | +| BondDid | `string` | | +| Order | `*SwapOrder` | | +| ChargedFee | `types.Coin` | | +| ReturnedToAddress | `github_com_cosmos_cosmos_sdk_types.Coins` | | +| TokensSwapped | `types.Coin` | | + +```go +type BondSwapOrderFulfilledEvent struct { + BondDid string + Order *SwapOrder + ChargedFee types.Coin + ReturnedToAddress github_com_cosmos_cosmos_sdk_types.Coins + TokensSwapped types.Coin +} +``` + +### BondBuyOrderCancelledEvent + +Emitted when a `BuyOrder` has been cancelled as it is not eligible to be executed anymore. + +| **Field** | **Type** | **Description** | +| :-------- | :---------- | :-------------- | +| BondDid | `string` | | +| Order | `*BuyOrder` | | + +```go +type BondBuyOrderCancelledEvent struct { + BondDid string + Order *BuyOrder +} +``` diff --git a/developers/ixo-blockchain/bonds/spec/06_params.md b/developers/ixo-blockchain/bonds/spec/06_params.md new file mode 100644 index 0000000..80d95df --- /dev/null +++ b/developers/ixo-blockchain/bonds/spec/06_params.md @@ -0,0 +1,7 @@ +# Parameters + +The bonds module contains the following parameter: + +| **Key** | **Type** | **Description** | +| :----------------- | :--------- | :----------------------------------------------------------- | +| ReservedBondTokens | `[]string` | A list of tokens that is reserved and can't be used by users | diff --git a/developers/ixo-blockchain/bonds/spec/07_future_improvements.md b/developers/ixo-blockchain/bonds/spec/07_future_improvements.md new file mode 100644 index 0000000..7220154 --- /dev/null +++ b/developers/ixo-blockchain/bonds/spec/07_future_improvements.md @@ -0,0 +1,10 @@ +# Future Improvements + +- **Order processing and front-running prevention**: Improved order fulfillment procedure with less cancellations and more options for the user when buying/selling/swapping, such as minimum returns, specifying amount to be spent rather than bought, etc. The intention is primarily to improve user experience. The main challenge lies in doing this without compromising on front-running prevention and order batching in general. More options for the user means more ways in which an order can be cancelled, and any cancelled order will affect the fulfillability of other orders, which may in turn get cancelled, and so on. One option would be to have an exchange-like behaviour and postpone orders that cannot be fulfilled to the next batch, which then runs into complications of dealing with stale orders. On a similar note, work can be done towards implementing front-running prevention for swap orders [1]. +- **Bond creation and function types**: More function types and an improved bond creation process, with more options for the creator and smarter parameter restrictions. An interesting function type that can be implemented is a rule-based function [2]. +- **IBC**: The availability of Inter-Blockchain Communication will unlock the full potential of the bonds module. On top of being able to create any bond, one will be able to use tokens from other chains as reserve tokens for the created bonds and transfer the bond tokens across chains. Further work would need to be done to ensure compatibility with IBC. + +## References + +1. https://ethresear.ch/t/improving-front-running-resistance-of-x-y-k-market-makers/1281 +2. https://medium.com/thoughtchains/on-single-bonding-curves-for-continuous-token-models-a167f5ffef89 \ No newline at end of file diff --git a/developers/ixo-blockchain/bonds/spec/08_functions_library.ipynb b/developers/ixo-blockchain/bonds/spec/08_functions_library.ipynb new file mode 100644 index 0000000..1705f8a --- /dev/null +++ b/developers/ixo-blockchain/bonds/spec/08_functions_library.ipynb @@ -0,0 +1,119 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "source": [ + "# Functions Library\n", + "The Bonds Module is deployed with a built-in set of libraries for commonly-used algorithmic pricing and reserve functions. It also includes algorithmic application logic and features, such as *Augmented Bonding*. Additional functions can be added to the Library through SDK updates. This requires a formal process of governance to approve updates, to assure the integrity of these functions.\n", + "\n", + "## Function Types\n", + "The following function types will be included in the standard Bonds SDK Module:\n", + "* Power (exponential)\n", + "* Logistic (sigmoidal)\n", + "* Constant Product (swapper)\n", + "* [Augmented Bonding Curves](https://medium.com/giveth/deep-dive-augmented-bonding-curves-3f1f7c1fa751) with [Alpha Bonds](https://github.com/BlockScience/Risk-Adjusted-Bonding-Curves) functionality (augmented)\n", + "\n", + "Algorithmic Applications include:\n", + "* Risk-adjusted bonding curves\n", + "* Innovation Bonds (offers bond shareholders contingent rights to future IP rights and/or revenues)\n", + "* Impact Bonds (offers bond shareholders contingent rights to success-based outcomes payments and/or rewards)\n", + "\n", + "### Exponential Function (power)\n", + "\n", + "Function (used as pricing function):\n", + "\n", + "$$y = mx^n + c$$\n", + "\n", + "Integral (used as reserve function):\n", + "\n", + "$$r = \\frac{m}{n+1}x^{n+1} + cx$$\n", + "\n", + "### Logistic Function (sigmoid)\n", + "\n", + "Function (used as pricing function):\n", + "\n", + "$$y = a \\cdot \\left( \\frac{x-b}{\\sqrt{c + (x-b)^2}} + 1 \\right)$$\n", + "\n", + "Integral (used as reserve function):\n", + "\n", + "$$y = a \\cdot \\left( \\sqrt{(x-b)^2 + c} + x \\right) - a \\cdot \\left( \\sqrt{b^2 + c} \\right) $$\n", + "\n", + "### Augmented Bonding Curves (augmented)\n", + "\n", + "#### Standard Augmented Bonding Curve Functions\n", + "\n", + "Initial reserve:\n", + "\n", + "$$R_0 = (1-\\theta)d_0$$\n", + "\n", + "Initial supply:\n", + "\n", + "$$S_0 = \\frac{d_0}{p_0}$$\n", + "\n", + "Constant power function invariant:\n", + "\n", + "$$V(R,S) = \\frac{S^\\kappa}{R}$$\n", + "\n", + "Invariant V function:\n", + "\n", + "$$V_0 = V(R_0,S_0) = \\frac{{S_0}^\\kappa}{R_0} = \\left( \\frac{1}{p_0 (1-\\theta)} \\right)^\\kappa {R_0}^{\\kappa - 1}$$\n", + "\n", + "Pricing function:\n", + "\n", + "$$P(R) = \\frac{\\kappa R^{(\\kappa - 1)/\\kappa}}{{V_0}^{1/\\kappa}}$$\n", + "\n", + "Reserve function:\n", + "\n", + "$$R(S) = \\frac{S^\\kappa}{V_0}$$\n", + "\n", + "Ref: https://medium.com/giveth/deep-dive-augmented-bonding-curves-3f1f7c1fa751\n", + "\n", + "#### Alpha Bonds Extension Functions\n", + "\n", + "Alpha:\n", + "\n", + "$$\\alpha = \\frac{S_1 R}{S_1 R - S_0 R + S_0 C}$$\n", + "\n", + "Invariant I:\n", + "\n", + "$$I = \\alpha C + R$$\n", + "\n", + "Kappa:\n", + "\n", + "$$\\kappa = \\frac{I}{I - \\alpha C}$$\n", + "\n", + "Ref: https://github.com/BlockScience/Risk-Adjusted-Bonding-Curves\n", + "\n", + "### Constant Product Function (swapper)\n", + "\n", + "Reserve function:\n", + "\n", + "$$x \\cdot y = k$$" + ], + "metadata": { + "collapsed": false + } + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.8.5" + } + }, + "nbformat": 4, + "nbformat_minor": 4 +} \ No newline at end of file diff --git a/developers/ixo-blockchain/bonds/spec/README.md b/developers/ixo-blockchain/bonds/spec/README.md new file mode 100644 index 0000000..efc30de --- /dev/null +++ b/developers/ixo-blockchain/bonds/spec/README.md @@ -0,0 +1,89 @@ +# Bonds module specification + +This document specifies the bonds module, a custom Ixo Cosmos SDK module. + +The bonds module provides universal token bonding curve functions to mint, burn or swap any token in a Cosmos blockchain. Once the Inter-Blockchain Communication (IBC) protocol is available, this should enable cross-network exchanges of tokens at algorithmically-determined prices. + +The bonds module can deliver applications such as: + +- Automated market-makers (like [Uniswap](https://uniswap.io)) +- Decentralised exchanges (like [Bancor](https://bancor.network)) +- Curation markets (like [Relevant](https://github.com/relevant-community/contracts/tree/bondingCurves/contracts)) +- Development Impact Bonds (like ixo alpha-Bonds) +- Continuous organisations (like [Moloch DAO](https://molochdao.com/)) + +Any Cosmos application chain that implements the Bonds module is able to perform functions such as: + +- Issue a new token with custom parameters. +- Pool liquidity for reserves. +- Provide continuous funding. +- Automatically mint and burn tokens at deterministic prices. +- Swap tokens atomically within the same network. +- Exchange tokens across networks, with the IBC protocol. +- (Batch token transactions to prevent front-running) +- Launch a decentralised autonomous initial coin offerings ([DAICO](https://ethresear.ch/t/explanation-of-daicos/465)) +- ..._other **DeFi**ant_ innovations. + +## Contents + +1. **[Concepts](01_concepts.md)** + + - [Concepts](01_concepts.md#concepts) + - [Token Bonding Curves](01_concepts.md#token-bonding-curves) + - [Token Bonds Module](01_concepts.md#token-bonds-module) + - [Batching](01_concepts.md#batching) + +2. **[State](02_state.md)** + + - [State](02_state.md#state) + - [Bonds](02_state.md#bonds) + - [Batches](02_state.md#batches) + - [Querying Batches](02_state.md#querying-batches) + +3. **[Messages](03_messages.md)** + + - [Messages](03_messages.md#messages) + - [MsgCreateBond](03_messages.md#msgcreatebond) + - [MsgEditBond](03_messages.md#msgeditbond) + - [MsgSetNextAlpha](03_messages.md#msgsetnextalpha) + - [MsgUpdateBondState](03_messages.md#msgupdatebondstate) + - [MsgBuy](03_messages.md#msgbuy) + - [MsgBuy for Swapper Function Bonds](03_messages.md#msgbuy-for-swapper-function-bonds) + - [MsgSell](03_messages.md#msgsell) + - [MsgSwap](03_messages.md#msgswap) + - [MsgMakeOutcomePayment](03_messages.md#msgmakeoutcomepayment) + - [MsgWithdrawShare](03_messages.md#msgwithdrawshare) + - [MsgWithdrawReserve](03_messages.md#msgwithdrawreserve) + +4. **[End-Block](04_end_block.md)** + + - [End-Block](04_end_block.md#end-block) + - [Buys](04_end_block.md#buys) + - [Sells](04_end_block.md#sells) + - [Swaps](04_end_block.md#swaps) + - [Set Last Batch](04_end_block.md#set-last-batch) + +5. **[Events](05_events.md)** + + - [Events](05_events.md#events) + - [BondCreatedEvent](05_events.md#bondcreatedevent) + - [BondUpdatedEvent](05_events.md#bondupdatedevent) + - [BondSetNextAlphaEvent](05_events.md#bondsetnextalphaevent) + - [BondBuyOrderEvent](05_events.md#bondbuyorderevent) + - [BondSellOrderEvent](05_events.md#bondsellorderevent) + - [BondSwapOrderEvent](05_events.md#bondswaporderevent) + - [BondMakeOutcomePaymentEvent](05_events.md#bondmakeoutcomepaymentevent) + - [BondWithdrawShareEvent](05_events.md#bondwithdrawshareevent) + - [BondWithdrawReserveEvent](05_events.md#bondwithdrawreserveevent) + - [BondEditAlphaSuccessEvent](05_events.md#bondeditalphasuccessevent) + - [BondEditAlphaFailedEvent](05_events.md#bondeditalphafailedevent) + - [BondBuyOrderFulfilledEvent](05_events.md#bondbuyorderfulfilledevent) + - [BondSellOrderFulfilledEvent](05_events.md#bondsellorderfulfilledevent) + - [BondSwapOrderFulfilledEvent](05_events.md#bondswaporderfulfilledevent) + - [BondBuyOrderCancelledEvent](05_events.md#bondbuyordercancelledevent) + +6. **[Parameters](06_params.md)** + +7. **[Future Improvements](07_future_improvements.md)** + +8. **[Functions Library](08_functions_library.ipynb)** diff --git a/developers/ixo-blockchain/claims/spec/01_concepts.md b/developers/ixo-blockchain/claims/spec/01_concepts.md new file mode 100644 index 0000000..7584d17 --- /dev/null +++ b/developers/ixo-blockchain/claims/spec/01_concepts.md @@ -0,0 +1,97 @@ +# Concepts + +## Verifiable Credentials (VCs) + +### What are Verifiable Credentials? + +Verifiable Credentials (VCs) are standardized digital statements made by the issuer about a subject. They serve as a cryptographically secure, tamper-evident, and privacy-preserving mechanism for presenting proofs about an individual's or entity's attributes or qualifications. This digital assertion allows an individual or entity to prove various facets of their identity or other claims without having to reveal excessive information. + +In the physical world, a driving license, a university degree, or a membership card can serve as credentials. In the digital realm, VCs replicate this concept, offering a digital equivalent that's cryptographically secure and verifiable. + +### Standards and Specifications + +VCs operate based on a standard laid out by the [World Wide Web Consortium (W3C)](https://www.w3.org/). This standard ensures that VCs are consistent, interoperable, and recognized across various digital platforms and applications. + +- [W3C Verifiable Credentials Data Model](https://www.w3.org/TR/vc-data-model/): This specification provides a detailed guide on how VCs are structured, issued, and verified. It establishes a foundation for building trust on the web, ensuring that digital attestations are as reliable as their physical counterparts. + +### Components of a Verifiable Credential + +1. **Issuer:** The authoritative entity that creates and signs the VC. The credibility of a VC often depends on the reputation of its issuer. +2. **Subject:** The individual or entity that the VC pertains to. It could be a person, organization, device, or any other entity that the claim is about. +3. **Claim:** The assertion or statement made about the subject. For example, a university (issuer) can assert that a student (subject) has achieved a particular degree (claim). +4. **Proof:** Cryptographic evidence that verifies the authenticity of the VC, ensuring that it hasn't been tampered with since its creation. This proof is typically a digital signature provided by the issuer. + +![VC-graph](./assets/vc_graph.svg) + +### Advantages of Verifiable Credentials + +- **Decentralization and Privacy:** VCs can be used without being tethered to a centralized authority after issuance. This decentralization means users can control and share their credentials without an intermediary, enhancing privacy. +- **Selective Disclosure:** Holders of VCs can choose which parts of their credentials they wish to share, offering finer control over personal data. +- **Interoperability:** Owing to the W3C standard, VCs can be seamlessly used across various platforms and services. +- **Security:** Cryptographic proofs ensure that VCs are tamper-evident and verifiable, instilling trust in their authenticity. + +### Use Cases + +VCs can be employed in a plethora of scenarios: + +- **Identity Verification:** Proving one's identity on online platforms without oversharing personal details. +- **Academic Credentials:** Sharing academic achievements and qualifications digitally. +- **Healthcare:** Sharing medical records or vaccination status in a secure and verifiable manner. +- **Financial Services:** Proving creditworthiness or transaction history. + +### In Summary + +Verifiable Credentials are a monumental step towards a more trustable and private digital ecosystem. By allowing individuals and entities to share and prove information about themselves without jeopardizing their privacy or data security, VCs are poised to redefine how we trust and verify data online. + +![VC-life](./assets/vc_life.svg) + +# Claims Module + +The Claims module in the ixo system facilitates the management and verification of claims, aligning with the W3C standards for Verifiable Credentials (VCs). + +## Overview + +VCs are digital attestations made by an issuer regarding a subject. These claims are both cryptographically secure and tamper-evident, ensuring their integrity. In the ixo system, the data model for a VC is defined by a **Claim Schema**. Each claim schema is established as part of a Protocol ([Entity](/x/entity/spec/02_state.md#entity) with type `protocol`) that includes a method for evaluating the claim and the criteria for its approval. + +Protocols in the ixo system are identifiable by an Entity Identifier in the DID format: `did:ixo:entity:{string}`. Each claim and its evaluation is distinguished by its unique `id`, which for example is the `cid` hash value, which also serves as its cryptographic proof. + +An ixo entity can have one or more claim protocols represented as a `linkedClaim`. Agents can be authorized by the entity to submit or evaluate claims, utilizing the entity's capability delegation verification method and issuing `authz` grants to these agents. + +## Key Features + +1. **Authorize Agents for Claim Submission:** + - Agents are individuals or entities with valid DIDs. + - The "service" agent, acting for an entity, can be a Group. This group can be: + - Any member from a predefined group member list. + - The Group by governance (referring to the group account). +2. **Authorize Agents for Claim Evaluation:** + + - The โevaluationโ agent acting on behalf of an entity can be a Group: + - Either any Member of a Group. + - Or the Group by governance. + - There's flexibility in evaluation: + - Multiple agents can be tasked to evaluate claims. + - A single claim can be assessed by multiple agents for additional insights (like getting a second opinion). + - Agents can be authorized for either a collection of claims or specifically identified ones. + - Agents can have constraints, like evaluating claims only within certain dates or evaluating a capped number of claims. + +3. **Registry Maintenance of Claims with Verification Proofs:** + + - Claims are organized under a [Collection](02_state.md#collection), where each collection contains claims submitted under a specific protocol for a distinct entity. Collections are identified by an `id` which is the [CollectionSequence](05_params.md). + - Every claim has a unique `id`, which is typically the CID, doubling as its cryptographic proof. + - Claims have a default `status` of `1`, indicating they've been `submitted`. Enum is [EvaluationStatus](02_state.md#evaluationstatus) + - After evaluation, a claim's status can change to: + - `approved` (=2) + - `rejected` (=3) + - `disputed` (=4) + +4. **Payment Authorization:** + + - Payments can be authorized to agents or evaluators' `account` upon various claim activities like submission, evaluation, approval, or when disputes arise. + +5. **Recording Counter-Claims Evidence:** + - In case of disputes, evidence for counter-claims can be recorded, facilitating transparency and conflict resolution. + +## Conclusion + +The Claims module is instrumental in the ixo system, providing a robust infrastructure for the creation, management, evaluation, and verification of claims. With the integration of the W3C standard for VCs, it ensures that all claims are both trustworthy and verifiable. diff --git a/developers/ixo-blockchain/claims/spec/02_state.md b/developers/ixo-blockchain/claims/spec/02_state.md new file mode 100644 index 0000000..7220752 --- /dev/null +++ b/developers/ixo-blockchain/claims/spec/02_state.md @@ -0,0 +1,406 @@ +# State + +## Collections + +A Collections is stored in the state and is accessed by the identity of the collection that is fetched and incremented onchain using the `Param`: `CollectionSequence`. + +- Collections: `0x01 | collectionId -> ProtocolBuffer(Collection)` + +## Claims + +A Claim is stored in the state and is accessed by the identity of the ClaimId(user provided). + +- Claims: `0x02 | claimId -> ProtocolBuffer(Claim)` + +## Disputes + +A Dispute is stored in the state and is accessed by the SubjectId of the dispute(user provided). + +- Disputes: `0x03 | disputeSubjectId(DID) -> ProtocolBuffer(Dispute)` + +# Types + +### Collection + +```go +type Collection struct { + Id string + Entity string + Admin string + Protocol string + StartDate *time.Time + EndDate *time.Time + Quota uint64 + Count uint64 + Evaluated uint64 + Approved uint64 + Rejected uint64 + Disputed uint64 + State CollectionState + Payments *Payments +} +``` + +The field's descriptions is as follows: + +- `id` - a string containing the collections identifier, it is incremented on chain for the collection of claims +- `entity` - a string containing the DID of the entity for which the claims are being created +- `admin` - a string containing the account address that will authorize or revoke agents and payments (the granter). It is the `Entity`'s [EntityAccount](/x/entity/spec/02_state.md#entityaccount) named `admin` +- `protocol` - a string containing the DID of the claim protocol +- `startDate` - a timestamp of the start date for the collection, after which claims may be submitted +- `endDate` - a timestamp of the end date for the collection, after which no more claims may be submitted (no endDate is allowed) +- `quota` - a integer containing the maximum number of claims that may be submitted, 0 is unlimited +- `count` - a integer containing the number of claims already submitted (internally calculated) +- `evaluated` - a integer containing the number of claims that have been evaluated (internally calculated) +- `approved` - a integer containing the number of claims that have been evaluated and approved (internally calculated) +- `rejected` - a integer containing the number of claims that have been evaluated and rejected (internally calculated) +- `disputed` - a integer containing the number of claims that have disputed status (internally calculated) +- `state` - a [CollectionState](#collectionstate) +- `payments` - a [Payments](#payments) + +### Payments + +A Payments stores [Payment](#payment) for the claim submission, evaluation, approval, or rejection payments made towards the collection + +```go +type Payments struct { + Submission *Payment + Evaluation *Payment + Approval *Payment + Rejection *Payment +} +``` + +The field's descriptions is as follows: + +- `submission` - a [Payment](#payment) +- `evaluation` - a [Payment](#payment) +- `approval` - a [Payment](#payment) +- `rejection` - a [Payment](#payment) + +### Payment + +A Payment stores information about the amount paid for claim submission, evaluation, approval, or rejection + +```go +type Payment struct { + Account string + Amount github_com_cosmos_cosmos_sdk_types.Coins + Contract_1155Payment *Contract1155Payment + TimeoutNs time.Duration +} +``` + +The field's descriptions is as follows: + +- `account` - a string containing the account address from which the payment will be made (ideally a [EntityAccount](/x/entity/spec/02_state.md#entityaccount)) +- `amount` - a [Coins](https://github.com/cosmos/cosmos-sdk/blob/main/types/coin.go#L180) object which denotes the coins and amount to be paid on payment +- `contract_1155Payment` - a [Contract1155Payment](#contract1155payment) +- `timeoutNs` - a duration containing the timeout after claim/evaluation to create authZ for payment, if 0 then immidiate direct payment is made + +### Contract1155Payment + +A Contract1155Payment stores information about the payment to make if it is a cw1155 tokens payment. + +```go +type Contract1155Payment struct { + Address string + TokenId string + Amount uint32 +} +``` + +The field's descriptions is as follows: + +- `address` - a string containing the smart contract address where the tokens can be transfered on (the cw1155 smart contract) +- `amount` - a integer indicating how many tokens must transfered for the payment +- `tokenId` - a string containing the `id` of the token on the cw1155 smart contract to transfer + +### Claim + +A Claim stores information about a claim that was made towards a [Collection](#collection) + +```go +type Claim struct { + CollectionId string + AgentDid string + AgentAddress string + SubmissionDate *time.Time + ClaimId string + Evaluation *Evaluation + PaymentsStatus *ClaimPayments +} +``` + +The field's descriptions is as follows: + +- `collectionId` - a string containing the Collection `id` this claim belongs +- `agentAddress` - a string containing the account address that submitted the claim +- `agentDid` - a string containing the Did of the agent that submitted the claim +- `submissionDate` - the timestamp of the date and time that the claim was submitted on-chain +- `claimId` - a string containing the unique identifier of the claim (eg. cid hash of file is good identifier) +- `evaluation` - a [Evaluation](#evaluation) +- `paymentsStatus` - a [ClaimPayments](#claimpayments) + +### ClaimPayments + +A ClaimPayments stores an enum for the status for the claim submission, evaluation, approval, or rejection payments + +```go +type ClaimPayments struct { + Submission PaymentStatus + Evaluation PaymentStatus + Approval PaymentStatus + Rejection PaymentStatus +} +``` + +The field's descriptions is as follows: + +- `submission` - a [PaymentStatus](#paymentstatus) +- `evaluation` - a [PaymentStatus](#paymentstatus) +- `approval` - a [PaymentStatus](#paymentstatus) +- `rejection` - a [PaymentStatus](#paymentstatus) + +### Evaluation + +A Evaluation stores information concerning the evaluation of a [Claim](#claim) made + +```go +type Evaluation struct { + ClaimId string + CollectionId string + Oracle string + AgentDid string + AgentAddress string + Status EvaluationStatus + Reason uint32 + VerificationProof string + EvaluationDate *time.Time + Amount github_com_cosmos_cosmos_sdk_types.Coins +} +``` + +The field's descriptions is as follows: + +- `claimId` - a string containing the `id` of the claim the evaluation is for +- `collectionId` - a string containing the Collection `id` the claim this evaluation is for belongs to +- `oracle` - a string containing the DID of the Oracle entity that evaluates the claim +- `agentAddress` - a string containing the account address that submitted the evaluation +- `agentDid` - a string containing the Did of the agent that submitted the evaluation +- `status` - a [EvaluationStatus](#evaluationstatus) +- `reason` - a integer for why the evaluation result was given (codes defined by evaluator) +- `verificationProof` - a string containing the proof to verify the linked resource (eg. the cid of the evaluation Verfiable Credential) +- `evaluationDate` - the timestamp of the date and time that the claim evaluation was submitted on-chain +- `amount` - a [Coins](https://github.com/cosmos/cosmos-sdk/blob/main/types/coin.go#L180) object which denotes the coins and amount to be paid on `Approval` payment if it is a custom amount and not the preset `Approval` from the [Collection](#collection) + +### Dispute + +A Dispute stores information concerning the dispute made towards a [Claim](#claim) + +```go +type Dispute struct { + SubjectId string + Type int32 + Data *DisputeData +} +``` + +The field's descriptions is as follows: + +- `subjectId` - a string containing the `id` of the claim the dispute is for. A unique field +- `type` - a integer interpreted by the client +- `data` - a [DisputeData](#disputedata) + +### DisputeData + +A DisputeData stores information concerning the data for a dispute made towards a [Claim](#claim) + +```go +type DisputeData struct { + Uri string + Type string + Proof string + Encrypted bool +} +``` + +The field's descriptions is as follows: + +- `uri` - a string representing the endpoint of the data linked resource +- `type ` - a string representing the [MIME](https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/MIME_types/Common_types) type of the data linked resource +- `proof ` - a string representing the proof to verify the data linked resource +- `encrypted ` - a boolean value for whether this data linked resource is encrypted or not + +## Enums + +### CollectionState + +Defines the `state` of a [Collection](#collection) denoting whether claims is allowed to be submitted or not. Already submitted claims is still allowed to be evaluated regardless of the `state` + +```go +var CollectionState_name = map[int32]string{ + 0: "OPEN", + 1: "PAUSED", + 2: "CLOSED", +} +``` + +### EvaluationStatus + +Defines the `status` of a [Evaluation](#evaluation) indicating the status and result of the evaluation. + +```go +var EvaluationStatus_name = map[int32]string{ + 0: "PENDING", + 1: "APPROVED", + 2: "REJECTED", + 3: "DISPUTED", +} +``` + +### PaymentType + +Defines the type of [Payment](#payment) used to keep track for payment withdrawals to update `ClaimPayments` accordingly + +```go +var PaymentType_name = map[int32]string{ + 0: "SUBMISSION", + 1: "APPROVAL", + 2: "EVALUATION", + 3: "REJECTION", +} +``` + +### PaymentStatus + +Defines the status of the payment types for `ClaimPayments` + +```go +var PaymentStatus_name = map[int32]string{ + 0: "NO_PAYMENT", + 1: "PROMISED", + 2: "AUTHORIZED", + 3: "GAURANTEED", + 4: "PAID", + 5: "FAILED", + 6: "DISPUTED", +} +``` + +## Authz Types + +### WithdrawPaymentAuthorization + +A WithdrawPaymentAuthorization is an authz authorization that can be granted to allow the grantee to make a withdrawal payout to receive his payment for claims submitted, evaluated or that was approved + +```go +type WithdrawPaymentAuthorization struct { + Admin string + Constraints []*WithdrawPaymentConstraints +} +``` + +The field's descriptions is as follows: + +- `admin` - a string containing the account address defined in the [Collection](02_state.md#collection) `admin` field +- `constraints` - a list of [WithdrawPaymentConstraints](#withdrawpaymentconstraints) + +### WithdrawPaymentConstraints + +A WithdrawPaymentConstraints stores information about authorization given to make a withdrawal payment through a [WithdrawPaymentAuthorization](#withdrawpaymentauthorization) + +```go +type WithdrawPaymentConstraints struct { + ClaimId string + Inputs []github_com_cosmos_cosmos_sdk_x_bank_types.Input + Outputs []github_com_cosmos_cosmos_sdk_x_bank_types.Output + PaymentType PaymentType + Contract_1155Payment *Contract1155Payment + ToAddress string + FromAddress string + ReleaseDate *time.Time +} +``` + +The field's descriptions is as follows: + +- `claimId` - a string containing the `id` of the claim the withdrawal is for +- `inputs` - a list of cosmos defined `Input` to pass to the the multisend tx to run to withdraw payment +- `outputs` - a list of cosmos defined `Output` to pass to the the multisend tx to run to withdraw payment +- `paymentType` - a [PaymentType](02_state.md#paymenttype) +- `contract_1155Payment` - a [Contract1155Payment](02_state.md#contract1155payment) +- `toAddress` - a string containing the account address to make the payment to +- `fromAddress` - a string containing the account address to make the payment from +- `releaseDate` - a timestamp of the date that grantee can execute authorization to make the withdrawal payment, calculated from created date plus the timeout on [Collection](02_state.md#collection) `Payments` +- `adminAddress` - a string containing the account address defined in the [Collection](02_state.md#collection) `admin` field + +### SubmitClaimAuthorization + +A SubmitClaimAuthorization is an authz authorization that can be granted to allow the grantee to submit claims for a specified collection + +```go +type SubmitClaimAuthorization struct { + Admin string + Constraints []*SubmitClaimConstraints +} +``` + +The field's descriptions is as follows: + +- `admin` - a string containing the account address defined in the [Collection](02_state.md#collection) `admin` field +- `constraints` - a list of [SubmitClaimConstraints](#submitclaimconstraints) + +### SubmitClaimConstraints + +A SubmitClaimConstraints stores information about authorization given to submit claims through a [SubmitClaimAuthorization](#submitclaimauthorization) + +```go +type SubmitClaimConstraints struct { + CollectionId string + AgentQuota uint64 +} +``` + +The field's descriptions is as follows: + +- `collectionId` - a string containing the Collection `id` the constraints is for +- `agentQuota` - a integer containing the quota for amount of time the grantee can execute the given authorization(authz) + +### EvaluateClaimAuthorization + +A EvaluateClaimAuthorization is an authz authorization that can be granted to allow the grantee to evaluate claims for a specified collection + +```go +type EvaluateClaimAuthorization struct { + Admin string + Constraints []*EvaluateClaimConstraints +} +``` + +The field's descriptions is as follows: + +- `admin` - a string containing the account address defined in the [Collection](02_state.md#collection) `admin` field +- `constraints` - a list of [EvaluateClaimConstraints](#evaluateclaimconstraints) + +### EvaluateClaimConstraints + +A EvaluateClaimConstraints stores information about authorization given to evaluate claims through a [EvaluateClaimAuthorization](#evaluateclaimauthorization) + +```go +type EvaluateClaimConstraints struct { + CollectionId string + ClaimIds []string + AgentQuota uint64 + BeforeDate *time.Time + MaxCustomAmount github_com_cosmos_cosmos_sdk_types.Coins +} +``` + +The field's descriptions is as follows: + +- `claimIds` - a list of strings containing all the id's of the claimsthe grantee is allowed to evaluate, can be an empty list to allow any claim +- `collectionId` - a string containing the Collection `id` the constraints is for +- `agentQuota` - a integer containing the quota for amount of time the grantee can execute the given authorization(authz) +- `beforeDate` - a timestamp of the date after which the grantee can't execute this authz anymore, a cut off date +- `MaxCustomAmount` - a [Coins](https://github.com/cosmos/cosmos-sdk/blob/main/types/coin.go#L180) object which denotes the coins and amount that indicates the maximum the evaluator is allowed to change the `APPROVED` payout to, since claims can be made for specific amount an evaluator is allowed to change the `APPROVED` payout amount. diff --git a/developers/ixo-blockchain/claims/spec/03_messages.md b/developers/ixo-blockchain/claims/spec/03_messages.md new file mode 100644 index 0000000..63a212f --- /dev/null +++ b/developers/ixo-blockchain/claims/spec/03_messages.md @@ -0,0 +1,136 @@ +# Messages + +In this section we describe the processing of the claims messages and the corresponding updates to the state. All created/modified state objects specified by each message are defined within the [state](./02_state.md) section. + +## MsgCreateCollection + +A `MsgCreateCollection` creates and stores a new Collection which defines protocols, quotas and payments for claim submissions and evaluations + +```go +type MsgCreateCollection struct { + Entity string + Signer string + Protocol string + StartDate *time.Time + EndDate *time.Time + Quota uint64 + State CollectionState + Payments *Payments +} +``` + +The field's descriptions is as follows: + +- `entity` - a string containing the DID of the entity for which the claims are being created +- `signer` - a string containing the account address of the private key signing the transaction +- `protocol` - a string containing the DID of the claim protocol +- `startDate` - a timestamp of the start date for the collection, after which claims may be submitted +- `endDate` - a timestamp of the end date for the collection, after which no more claims may be submitted (no endDate is allowed) +- `quota` - a integer containing the maximum number of claims that may be submitted, 0 is unlimited +- `state` - a [CollectionState](02_state.md#collectionstate) +- `payments` - a [Payments](02_state.md#payments) + +## MsgSubmitClaim + +A `MsgSubmitClaim` creates and stores a new Claim made towards a `Collection`. On Submission of claim `SUBMISSION` payments will be made if there is any defined in the [Collection](02_state.md#collection) `Payments`. + +```go +type MsgSubmitClaim struct { + CollectionId string + ClaimId string + AgentDid DIDFragment + AgentAddress string + AdminAddress string +} +``` + +The field's descriptions is as follows: + +- `collectionId` - a string containing the Collection `id` this claim belongs +- `agentAddress` - a string containing the account address that is submitting the claim +- `agentDid` - a string containing the Did of the agent that is submitting the claim +- `adminAddress` - a string containing the account address defined in the [Collection](02_state.md#collection) `admin` field + +## MsgEvaluateClaim + +A `MsgEvaluateClaim` updates the `Evaluation` for a claim. On evaluation payments will be made for both the evaluation of the claim (towards the agent or oracle) as well as if the claim was `APPROVED` then the claim submitter will also get a payment, which will the preset amount defined on th [Collection](02_state.md#collection) `Payments` field or the evaluator can also define a custom `Amount` that can be paid out on approval. + +```go +type MsgEvaluateClaim struct { + ClaimId string + CollectionId string + Oracle string + AgentDid DIDFragment + AgentAddress string + AdminAddress string + Status EvaluationStatus + Reason uint32 + VerificationProof string + Amount github_com_cosmos_cosmos_sdk_types.Coins +} +``` + +The field's descriptions is as follows: + +- `claimId` - a string containing the `id` of the claim the evaluation is for +- `collectionId` - a string containing the Collection `id` the claim this evaluation is for belongs to +- `oracle` - a string containing the DID of the Oracle entity that is evaluating the claim +- `agentAddress` - a string containing the account address that is submitting the evaluation +- `agentDid` - a string containing the Did of the agent that is submitting the evaluation +- `adminAddress` - a string containing the account address defined in the [Collection](02_state.md#collection) `admin` field +- `status` - a [EvaluationStatus](#evaluationstatus) +- `reason` - a integer for why the evaluation result was given (codes defined by evaluator) +- `verificationProof` - a string containing the proof to verify the linked resource (eg. the cid of the evaluation Verfiable Credential) +- `amount` - a [Coins](https://github.com/cosmos/cosmos-sdk/blob/main/types/coin.go#L180) object which denotes the coins and amount to be paid on `Approval` payment if it is a custom amount and not the preset `Approval` from the [Collection](#collection) + +## MsgDisputeClaim + +A `MsgDisputeClaim` creates and stores a new Dispute. + +```go +type MsgDisputeClaim struct { + SubjectId string + AgentDid DIDFragment + AgentAddress string + DisputeType int32 + Data *DisputeData +} +``` + +The field's descriptions is as follows: + +- `subjectId` - a string containing the `id` of the claim the dispute is for. A unique field +- `disputeType` - a integer interpreted by the client +- `data` - a [DisputeData](02_state.md#disputedata) +- `agentAddress` - a string containing the account address that is submitting the dispute +- `agentDid` - a string containing the Did of the agent that is submitting the dispute + +## MsgWithdrawPayment + +A `MsgWithdrawPayment` creates and stores a new Withdrawal Payment which contains details about a payment that can be made if the `TimeoutNs` in a [Payment](02_state.md#payment) is non 0, which means the payout won't happen on submission/evaluation but an authz gets granted with the receiver as grantee that allows the execution of this message after the `ReleaseDate`. This will allow the receiver to execute the payout through a [MsgExec](https://docs.cosmos.network/main/build/modules/authz#msgexec) to execute the authz. + +```go +type MsgWithdrawPayment struct { + ClaimId string + Inputs []github_com_cosmos_cosmos_sdk_x_bank_types.Input + Outputs []github_com_cosmos_cosmos_sdk_x_bank_types.Output + PaymentType PaymentType + Contract_1155Payment *Contract1155Payment + ToAddress string + FromAddress string + ReleaseDate *time.Time + AdminAddress string +} +``` + +The field's descriptions is as follows: + +- `claimId` - a string containing the `id` of the claim the withdrawal is for +- `inputs` - a list of cosmos defined `Input` to pass to the the multisend tx to run to withdraw payment +- `outputs` - a list of cosmos defined `Output` to pass to the the multisend tx to run to withdraw payment +- `paymentType` - a [PaymentType](02_state.md#paymenttype) +- `contract_1155Payment` - a [Contract1155Payment](02_state.md#contract1155payment) +- `toAddress` - a string containing the account address to make the payment to +- `fromAddress` - a string containing the account address to make the payment from +- `releaseDate` - a timestamp of the date that grantee can execute authorization to make the withdrawal payment, calculated from created date plus the timeout on [Collection](02_state.md#collection) `Payments` +- `adminAddress` - a string containing the account address defined in the [Collection](02_state.md#collection) `admin` field diff --git a/developers/ixo-blockchain/claims/spec/04_events.md b/developers/ixo-blockchain/claims/spec/04_events.md new file mode 100644 index 0000000..3d29b43 --- /dev/null +++ b/developers/ixo-blockchain/claims/spec/04_events.md @@ -0,0 +1,115 @@ +# Events + +The bonds module emits the following typed events: + +### CollectionCreatedEvent + +Emitted after a successfull `MsgCreateCollection` + +```go +type CollectionCreatedEvent struct { + Collection *Collection +} +``` + +The field's descriptions is as follows: + +- `collection` - the full [Collection](02_state.md#collection) + +### CollectionUpdatedEvent + +Emitted after a successfull `MsgSubmitClaim`, `EvaluateClaim` since collection holds a count of claims + +```go +type CollectionUpdatedEvent struct { + Collection *Collection +} +``` + +The field's descriptions is as follows: + +- `collection` - the full [Collection](02_state.md#collection) + +### ClaimSubmittedEvent + +Emitted after a successfull `MsgSubmitClaim` + +```go +type ClaimSubmittedEvent struct { + Claim *Claim +} +``` + +The field's descriptions is as follows: + +- `claim` - the full [Claim](02_state.md#claim) + +### ClaimUpdatedEvent + +Emitted after a successfull `MsgEvaluateClaim` or when the state for the `ClaimPayments` changes. + +```go +type ClaimUpdatedEvent struct { + Claim *Claim +} +``` + +The field's descriptions is as follows: + +- `claim` - the full [Claim](02_state.md#claim) + +### ClaimEvaluatedEvent + +Emitted after a successfull `MsgEvaluateClaim` + +```go +type ClaimEvaluatedEvent struct { + Evaluation *Evaluation +} +``` + +The field's descriptions is as follows: + +- `evaluation` - the full [Evaluation](02_state.md#evaluation) + +### ClaimDisputedEvent + +Emitted after a successfull `MsgDisputeClaim` + +```go +type ClaimDisputedEvent struct { + Dispute *Dispute +} +``` + +The field's descriptions is as follows: + +- `dispute` - the full [Dispute](02_state.md#dispute) + +### PaymentWithdrawnEvent + +Emitted after a successfull `MsgWithdrawPayment` or when a payment gets withdrawn through another trigger like payments on evaluation with 0 timeout. + +```go +type PaymentWithdrawnEvent struct { + Withdraw *WithdrawPaymentConstraints +} +``` + +The field's descriptions is as follows: + +- `withdraw` - the full [WithdrawPaymentConstraints](02_state.md#withdrawpaymentconstraints) + +### PaymentWithdrawCreatedEvent + +Emitted after a successfull payment withdrawal authz gets created on chain if the `Payments` `timeout_ns` is not 0, and a [WithdrawPaymentAuthorization](02_state.md#withdrawpaymentauthorization) is created with the receiver as the grantee + +```go +type PaymentWithdrawCreatedEvent struct { + Withdraw *WithdrawPaymentConstraints +} +``` + +The field's descriptions is as follows: + +- `withdraw` - the full [WithdrawPaymentConstraints](02_state.md#withdrawpaymentconstraints) diff --git a/developers/ixo-blockchain/claims/spec/05_params.md b/developers/ixo-blockchain/claims/spec/05_params.md new file mode 100644 index 0000000..35ed303 --- /dev/null +++ b/developers/ixo-blockchain/claims/spec/05_params.md @@ -0,0 +1,10 @@ +# Parameters + +The claims module contains the following parameter: + +| **Key** | **Type** | **Description** | +| :------------------- | :--------------------------------------- | :---------------------------------------------------------------------------------------------------------------------------------------- | +| CollectionSequence | `uint64` | An onchain sequence to generate collection ids | +| IxoAccount | `string` | The Ixo network account address that will receive it's `NetworkFeePercentage` for every claim evaluation | +| NetworkFeePercentage | `github_com_cosmos_cosmos_sdk_types.Dec` | The percentage that the `IxoAccount` param account will receive for every claim evaluation | +| NodeFeePercentage | `github_com_cosmos_cosmos_sdk_types.Dec` | The percentage that the node relayer for the given marketplace that the collection was created in will receive for every claim evaluation | diff --git a/developers/ixo-blockchain/claims/spec/06_future_improvements.md b/developers/ixo-blockchain/claims/spec/06_future_improvements.md new file mode 100644 index 0000000..44ef026 --- /dev/null +++ b/developers/ixo-blockchain/claims/spec/06_future_improvements.md @@ -0,0 +1,13 @@ +# Future Improvements + +The ixo system continually evolves to offer more sophisticated, efficient, and streamlined solutions. Some proposed enhancements in the pipeline for the Claims module include: + +### Agent Authorization for Group Accounts + +To diminish the administrative overhead, agents could be authorized not just for individual accounts but for group accounts. Consider a scenario involving a Project Entity with a defined group of Service Agents. Any member from this group might have the capability to submit claims. The essential task then is only to oversee and manage the group membership, which happens outside the purview of the Claims module. + +### Auto-Authorization for Claim Submission + +In scenarios like public campaigns where agent identification isn't crucial, agents might be permitted to submit claims without preliminary authorization. This open approach, however, carries risks like potential spamming or DDoS attacks. To mitigate such threats, a proposal suggests limiting each agent DID to submit only a defined number of claims. + +These planned improvements emphasize the commitment to making the Claims module more adaptive and in tune with diverse project requirements while preserving system security and efficiency. diff --git a/developers/ixo-blockchain/claims/spec/README.md b/developers/ixo-blockchain/claims/spec/README.md new file mode 100644 index 0000000..3b8fe44 --- /dev/null +++ b/developers/ixo-blockchain/claims/spec/README.md @@ -0,0 +1,67 @@ +# Claims module specification + +This document specifies the claims module, a custom Ixo Cosmos SDK module. + +The Claims Module provides an advanced structure for handling Verifiable Claims (VCs), cryptographic attestations regarding a subject. By aligning with the W3C standard and incorporating unique ixo system identifiers, this module offers a comprehensive solution for creating, evaluating, and managing claims. It enables entities to define protocols, authorize agents, and maintain a verifiable registry, ensuring authenticity and transparency in all claim-related processes. + +## Contents + +1. **[Concepts](01_concepts.md)** + + - [Concepts](01_concepts.md#concepts) + - [Verifiable Credentials (VCs)](01_concepts.md#verifiable-credentials-vcs) + - [Claims Module](01_concepts.md#claims-module) + +2. **[State](02_state.md)** + + - [State](02_state.md#state) + - [Collections](02_state.md#collections) + - [Claims](02_state.md#claims) + - [Disputes](02_state.md#disputes) + - [Types](02_state.md#types) + - [Collection](02_state.md#collection) + - [Payments](02_state.md#payments) + - [Payment](02_state.md#payment) + - [Contract1155Payment](02_state.md#contract1155payment) + - [Claim](02_state.md#claim) + - [ClaimPayments](02_state.md#claimpayments) + - [Evaluation](02_state.md#evaluation) + - [Dispute](02_state.md#dispute) + - [DisputeData](02_state.md#disputedata) + - [Enums](02_state.md#enums) + - [CollectionState](02_state.md#collectionstate) + - [EvaluationStatus](02_state.md#evaluationstatus) + - [PaymentType](02_state.md#paymenttype) + - [PaymentStatus](02_state.md#paymentstatus) + - [Authz Types](02_state.md#authz-types) + - [WithdrawPaymentAuthorization](02_state.md#withdrawpaymentauthorization) + - [WithdrawPaymentConstraints](02_state.md#withdrawpaymentconstraints) + - [SubmitClaimAuthorization](02_state.md#submitclaimauthorization) + - [SubmitClaimConstraints](02_state.md#submitclaimconstraints) + - [EvaluateClaimAuthorization](02_state.md#evaluateclaimauthorization) + - [EvaluateClaimConstraints](02_state.md#evaluateclaimconstraints) + +3. **[Messages](03_messages.md)** + + - [Messages](03_messages.md#messages) + - [MsgCreateCollection](03_messages.md#msgcreatecollection) + - [MsgSubmitClaim](03_messages.md#msgsubmitclaim) + - [MsgEvaluateClaim](03_messages.md#msgevaluateclaim) + - [MsgDisputeClaim](03_messages.md#msgdisputeclaim) + - [MsgWithdrawPayment](03_messages.md#msgwithdrawpayment) + +4. **[Events](04_events.md)** + + - [Events](04_events.md#events) + - [CollectionCreatedEvent](04_events.md#collectioncreatedevent) + - [CollectionUpdatedEvent](04_events.md#collectionupdatedevent) + - [ClaimSubmittedEvent](04_events.md#claimsubmittedevent) + - [ClaimUpdatedEvent](04_events.md#claimupdatedevent) + - [ClaimEvaluatedEvent](04_events.md#claimevaluatedevent) + - [ClaimDisputedEvent](04_events.md#claimdisputedevent) + - [PaymentWithdrawnEvent](04_events.md#paymentwithdrawnevent) + - [PaymentWithdrawCreatedEvent](04_events.md#paymentwithdrawcreatedevent) + +5. **[Parameters](05_params.md)** + +6. **[Future Improvements](06_future_improvements.md)** diff --git a/developers/ixo-blockchain/claims/spec/assets/vc_graph.svg b/developers/ixo-blockchain/claims/spec/assets/vc_graph.svg new file mode 100644 index 0000000..5d88c55 --- /dev/null +++ b/developers/ixo-blockchain/claims/spec/assets/vc_graph.svg @@ -0,0 +1,111 @@ + diff --git a/developers/ixo-blockchain/claims/spec/assets/vc_life.svg b/developers/ixo-blockchain/claims/spec/assets/vc_life.svg new file mode 100644 index 0000000..9b17605 --- /dev/null +++ b/developers/ixo-blockchain/claims/spec/assets/vc_life.svg @@ -0,0 +1,81 @@ + + diff --git a/developers/ixo-blockchain/entity/spec/01_concepts.md b/developers/ixo-blockchain/entity/spec/01_concepts.md new file mode 100644 index 0000000..15a65d7 --- /dev/null +++ b/developers/ixo-blockchain/entity/spec/01_concepts.md @@ -0,0 +1,43 @@ +# Entity Module + +The `Entity` module is a pivotal component of our blockchain system, facilitating the unified management of both non-fungible tokens (NFTs) and their associated Interchain Identifiers (IIDs). By seamlessly intertwining NFTs with IIDs, the `Entity` module establishes a new paradigm for decentralized asset management, bolstered by the credibility and dependability of DID Documents. + +## Overview + +When an `Entity` is created on the blockchain, a trifecta of operations is set into motion: + +1. An IID Document is birthed through the `iid` module, cementing the foundational identity and associated metadata of the entity. +2. An NFT is minted using the CW721 smart contract, capturing the unique and immutable essence of the entity in tokenized form. +3. A dedicated `Entity` data structure is etched into the KV store. This is not merely a reflection of the IID Document; it captures supplementary metadata exclusive to the `Entity`, enhancing its depth and versatility. + +The `id` for all 3 of the different data stored above is deterministically determined on-chain on Entity creation. + +## Key Components + +### Entity Data Structure + +Stored within the KV store, the `Entity` data structure houses metadata that isn't contained within the IID Document. It's instrumental in furnishing a holistic view of the `Entity`, encapsulating both inherent and appended attributes. This data provides richer context, driving interoperability and comprehensive understanding across platforms and applications. + +#### Entity Accounts + +An Entity Account is a Cosmos Module Account that can only be created and controlled by an Entity Owner. An Entity may have any number of Entity Accounts. Each Entity Account has a unique name. For instance โSavingsโ. The account address is derived from this name and the DID of the Entity. The Entity Owner may authorise any other account to perform transactions for an Entity Account, using Authz. When ownership of an Entity is transferred, the new owner gains control of the Entity Accounts. All residual balances in an Entity Account get transferred together with the Entity NFT when ownership is transferred. + +On Entity creation a default Entity Account gets created with the name `admin`. + +### NFT Creation + +The minting of an NFT via the CW721 smart contract reaffirms the distinctiveness of each `Entity`. This tokenized representation not only encapsulates the essence of the entity but also offers a myriad of possibilities in terms of trade, ownership verification, and utilization in decentralized applications. + +### IID Document Creation + +The automatic generation of an IID Document ensures that every `Entity` is backed by a standardized, robust, and decentralized identity mechanism. This identity is enriched with crucial metadata and, being compliant with W3C's DID specifications, offers global compatibility and recognition. + +### Advantages + +- **Unified Management:** The `Entity` module simplifies the intricacies of managing decentralized assets by unifying IID creation, NFT minting, and metadata storage. +- **Enhanced Metadata:** By preserving additional metadata in the `Entity` data structure, a comprehensive and nuanced understanding of each entity is achieved. +- **Interoperability:** Rooted in globally recognized standards, `Entities` foster seamless interactions across various decentralized platforms and applications. + +- **Decentralization and Security:** The tandem of IID Documents and NFTs ensures a decentralized, tamper-proof, and transparent representation of entities. + +For a deeper dive into the foundational principles of IIDs, consult the [`iid` module documentation](/x/iid/spec/README.md). For a comprehensive understanding of NFTs and the CW721 standard, refer to the [official CW721 documentation](https://github.com/CosmWasm/cw-nfts/blob/main/packages/cw721/README.md) which follows the [eip721 standard](https://eips.ethereum.org/EIPS/eip-721). diff --git a/developers/ixo-blockchain/entity/spec/02_state.md b/developers/ixo-blockchain/entity/spec/02_state.md new file mode 100644 index 0000000..a5a6f5e --- /dev/null +++ b/developers/ixo-blockchain/entity/spec/02_state.md @@ -0,0 +1,73 @@ +# State + +## Entities + +A Entity is stored in the state and is accessed by the identity of the entity(DID). + +- Entities: `0x01 | entityId(DID) -> ProtocolBuffer(Entity)` + +# Types + +### Entity + +```go +type Entity struct { + Id string + Type string + StartDate *time.Time + EndDate *time.Time + Status int32 + RelayerNode string + Credentials []string + EntityVerified bool + Accounts []*EntityAccount + Metadata *EntityMetadata +} +``` + +The field's descriptions is as follows: + +- `id` - a string containing the unique identifier of the entity +- `type` - a string representing the type of entity it is eg, `dao`, `protocol`, `asset/device` +- `startDate` - a timestamp of the start date for the entity, as defined by the implementer and interpreted by client applications +- `endDate` - a timestamp of the end date for the entity, as defined by the implementer and interpreted by client applications +- `status` - a integer representing the status of the entity, as defined by the implementer and interpreted by client applications +- `relayerNode` - a string representing the did id of the operator through which the entity was created +- `credentials` - a list of string representing the credentials of the enitity to be verified +- `entityVerified` - a boolean used as check whether the credentials of entity is verified +- `accounts` - a list of [EntityAccount](#entityaccount) +- `metadata` - a [EntityMetadata](#entitymetadata) + +### EntityAccount + +A EntityAccount is a module account generated deterministically using the entity id and name for the account and can only be controlled through the entity owner. + +```go +type EntityAccount struct { + Name string + Address string +} +``` + +The field's descriptions is as follows: + +- `name` - a string representing the name for the [Entity Account](01_concepts.md#entity-accounts) +- `address` - a string containing the address of the [Entity Account](01_concepts.md#entity-accounts) + +### EntityMetadata + +A EntityMetadata stores information relative to a Entity such as versionId, created, and updated. + +```go +type EntityMetadata struct { + VersionId string + Created *time.Time + Updated *time.Time +} +``` + +The field's descriptions is as follows: + +- `versionId` - the version of the last update operation for the entity +- `updated` - the timestamp of the last update operation for the entity +- `created` - the timestamp of the create operation diff --git a/developers/ixo-blockchain/entity/spec/03_messages.md b/developers/ixo-blockchain/entity/spec/03_messages.md new file mode 100644 index 0000000..6187ba4 --- /dev/null +++ b/developers/ixo-blockchain/entity/spec/03_messages.md @@ -0,0 +1,157 @@ +# Messages + +In this section we describe the processing of the entity messages and the corresponding updates to the state. All created/modified state objects specified by each message are defined within the [state](./02_state.md) section. + +## MsgCreateEntity + +A `MsgCreateEntity` creates and stores a new entity doc and a corresponding iid doc with the same id(DID) along with its nft at +appropriate indexes, which is a nft on a cw721 smart contract. It includes the [MsgCreateIidDocument](/x/iid/spec/03_messages.md#msgcreateiiddocument) fields also since creating an entity also creates a corresponding [IidDocument](/x/iid/spec/02_state.md#iiddocument) with the same id as the id generated for the entity. + +```go +type MsgCreateEntity struct { + EntityType string + EntityStatus int32 + Controller []string + Context []*types.Context + Verification []*types.Verification + Service []*types.Service + AccordedRight []*types.AccordedRight + LinkedResource []*types.LinkedResource + LinkedEntity []*types.LinkedEntity + StartDate *time.Time + EndDate *time.Time + RelayerNode string + Credentials []string + OwnerDid DIDFragment + OwnerAddress string + Data encoding_json.RawMessage + AlsoKnownAs string + LinkedClaim []*types.LinkedClaim +} +``` + +The field's descriptions is as follows: + +- `entityType` - a string representing the type of entity it is eg, `dao`, `protocol`, `asset/device` +- `entityStatus` - a integer representing the status of the entity, as defined by the implementer and interpreted by client applications +- `context` - a list of [Context](/x/iid/spec/02_state.md#context) +- `controllers` - a list of strings of controllers(DIDs). A DID controller is an entity that is authorized to make changes to a DID document. https://www.w3.org/TR/did-core/#did-controller +- `verifications` - a list of [Verifications](/x/iid/spec/02_state.md#verification) +- `service` - a list of [Service](/x/iid/spec/02_state.md#service) +- `linkedResource` - a list of [LinkedResource](/x/iid/spec/02_state.md#linked-resource) +- `accordedRight` - a list of [AccordedRight](/x/iid/spec/02_state.md#accorded-right) +- `linkedEntity` - a list of [LinkedEntity](/x/iid/spec/02_state.md#linked-entity) +- `linkedClaim` - a list of [LinkedClaim](/x/iid/spec/02_state.md#linked-claim) +- `alsoKnownAs` - a string. The assertion that two or more DIDs (or other types of URI) refer to the same DID subject can be made using the alsoKnownAs property. https://www.w3.org/TR/did-core/#also-known-as +- `ownerAddress` - a string containing the cosmos address of the private key signing the transaction +- `ownerDid` - a string containing the [MsgCreateIidDocument](/x/iid/spec/03_messages.md#msgcreateiiddocument) id (aka DID) of the owner which will be added to the [IidDocument](/x/iid/spec/02_state.md#iiddocument) list of controllers +- `startDate` - a timestamp of the start date for the entity, as defined by the implementer and interpreted by client applications +- `endDate` - a timestamp of the end date for the entity, as defined by the implementer and interpreted by client applications +- `relayerNode` - a string representing the did id of the operator through which the entity was created +- `credentials` - a list of string representing the credentials of the enitity to be verified + +## MsgUpdateEntity + +The `MsgUpdateEntity` is used to update an entity. It updates the entity with all the fields, so if a field is empty it will be updated with default go type, aka never null. For this reason also provide the previous values for fields you do not wish to update. + +```go +type MsgUpdateEntity struct { + Id string + EntityStatus int32 + StartDate *time.Time + EndDate *time.Time + Credentials []string + ControllerDid DIDFragment + ControllerAddress string +} +``` + +The field's descriptions is as follows: + +- `id` - a string containing the unique identifier of the entity. +- `entityStatus` - a integer representing the status of the entity, as defined by the implementer and interpreted by client applications +- `startDate` - a timestamp of the start date for the entity, as defined by the implementer and interpreted by client applications +- `endDate` - a timestamp of the end date for the entity, as defined by the implementer and interpreted by client applications +- `credentials` - a list of string representing the credentials of the enitity to be verified +- `ControllerAddress` - a string containing the cosmos address of the private key signing the transaction +- `ControllerDid` - a string containing the signers IidDocument Id. Must be in the IidDocument's controllers list to allow update and the `ControllerAddress` must be authorized to sign on behalf of the `ControllerDid` + +## MsgUpdateEntityVerified + +The `MsgUpdateEntityVerified` is used to update the `EntityVerified` field of an entity. Only the relayerNode for the entity can update it. + +```go +type MsgUpdateEntityVerified struct { + Id string + EntityVerified bool + RelayerNodeDid DIDFragment + RelayerNodeAddress string +} +``` + +The field's descriptions is as follows: + +- `id` - a string containing the unique identifier of the entity. +- `entityVerified` - a boolean indicating whether the entity is verified or not, can be based on credentials +- `relayerNodeAddress` - a string containing the cosmos address of the private key signing the transaction +- `relayerNodeDid` - a string containing the signers IidDocument Id. Must be in the `RelayerNode` of the entity and the `RelayerNodeAddress` must be authorized to sign on behalf of the `RelayerNodeDid` + +## MsgTransferEntity + +The `MsgTransferEntity` is used to transfer an entity to a new user. It will change the controllers on the [IidDocument](/x/iid/spec/02_state.md#iiddocument) to the `recipientDid` as well as remove all the [Verification Method](/x/iid/spec/02_state.md#verification-method) and add the the `recipientDid` as a new one. It also transfers the nft representing the entity on the cw721 smart contract to the recipient. + +```go +type MsgTransferEntity struct { + Id string + OwnerDid DIDFragment + OwnerAddress string + RecipientDid DIDFragment +} +``` + +The field's descriptions is as follows: + +- `id` - a string containing the unique identifier of the entity. +- `recipientDid` - a string containing the recipient IidDocument Id (Did). +- `ownerAddress` - a string containing the cosmos address of the private key signing the transaction +- `ownerDid` - a string containing the signers IidDocument Id. Must be in the IidDocument's controllers list to allow update and the `ownerAddress` must be authorized to sign on behalf of the `ownerDid` + +## MsgCreateEntityAccount + +The `MsgCreateEntityAccount` is used to create additional [Entity Accounts](02_state.md#entityaccount). + +```go +type MsgCreateEntityAccount struct { + Id string + Name string + OwnerAddress string +} +``` + +The field's descriptions is as follows: + +- `id` - a string containing the unique identifier of the entity. +- `name` - a string containing the name for the new entity account. +- `ownerAddress` - a string containing the cosmos address of the private key signing the transaction + +## MsgGrantEntityAccountAuthz + +The `MsgGrantEntityAccountAuthz` is used to create an [Authz](https://docs.cosmos.network/main/build/modules/authz) grant from entity account (as granter) to the msg `GranteeAddress` for the specific authorization + +```go +type MsgGrantEntityAccountAuthz struct { + Id string + Name string + GranteeAddress string + Grant github_com_cosmos_cosmos_sdk_x_authz.Grant + OwnerAddress string +} +``` + +The field's descriptions is as follows: + +- `id` - a string containing the unique identifier of the entity. +- `name` - a string containing the name for the entity account to use as granter for the authz grant. +- `granteeAddress` - a string containing the grantee address for the authz grant. +- `grant` - a [Grant](https://docs.cosmos.network/main/build/modules/authz#grant) that will be created. +- `ownerAddress` - a string containing the cosmos address of the private key signing the transaction diff --git a/developers/ixo-blockchain/entity/spec/04_events.md b/developers/ixo-blockchain/entity/spec/04_events.md new file mode 100644 index 0000000..3c37cb7 --- /dev/null +++ b/developers/ixo-blockchain/entity/spec/04_events.md @@ -0,0 +1,115 @@ +# Events + +The entity module emits the following typed events: + +### EntityCreatedEvent + +Emitted after a successfull `MsgCreateEntity` + +```go +type EntityCreatedEvent struct { + Entity *Entity + Signer string +} +``` + +The field's descriptions is as follows: + +- `entity` - the full [Entity](02_state.md#entity) +- `signer` - a string containing the did of the signer. + +### EntityUpdatedEvent + +Emitted after a successfull `MsgUpdateEntity`, `MsgUpdateEntityVerified`, `MsgTransferEntity`, `MsgCreateEntityAccount` whereby a field of the entity struct gets updated. + +```go +type EntityUpdatedEvent struct { + Entity *Entity + Signer string +} +``` + +The field's descriptions is as follows: + +- `entity` - the full [Entity](02_state.md#entity) +- `signer` - a string containing the did of the signer or the address of the signer. + +### EntityVerifiedUpdatedEvent + +Emitted after a successfull `MsgUpdateEntityVerified` + +```go +type EntityVerifiedUpdatedEvent struct { + Id string + Signer string + EntityVerified bool +} +``` + +The field's descriptions is as follows: + +- `id` - a string containing the unique identifier of the entity. +- `signer` - a string containing the did of the signer (will the `relayerNode` did in this case). +- `entityVerified` - a boolean indicating whether the entity is verified or not. + +### EntityTransferredEvent + +Emitted after a successfull `MsgTransferEntity` + +```go +type EntityTransferredEvent struct { + Id string + From string + To string +} +``` + +The field's descriptions is as follows: + +- `id` - a string containing the unique identifier of the entity. +- `to` - a string containing the did of the new owner. +- `from` - a string containing the did of the previous owner. + +### EntityAccountCreatedEvent + +Emitted after a successfull `MsgCreateEntityAccount` + +```go +type EntityAccountCreatedEvent struct { + Id string + Signer string + AccountName string + AccountAddress string +} +``` + +The field's descriptions is as follows: + +- `id` - a string containing the unique identifier of the entity. +- `accountName` - a string containing the name of the new entity account. +- `accountAddress` - a string containing the address of the new entity account. +- `signer` - a string containing the address of the signer. + +### EntityAccountAuthzCreatedEvent + +Emitted after a successfull `MsgGrantEntityAccountAuthz` + +```go +type EntityAccountAuthzCreatedEvent struct { + Id string + Signer string + AccountName string + Granter string + Grantee string + Grant *Grant +} +``` + +The field's descriptions is as follows: + +- `id` - a string containing the unique identifier of the entity. +- `signer` - a string containing the address of the signer. +- `accountName` - a string containing the name of the entity account the authz was granted. +- `granter` - a string containing the address of the entity account the authz was granted. +- `grantee` - a string containing the address of the grantee towards who the authz was granted. +- `grant` - the [Grant](https://docs.cosmos.network/main/build/modules/authz#grant) that was granted. diff --git a/developers/ixo-blockchain/entity/spec/05_params.md b/developers/ixo-blockchain/entity/spec/05_params.md new file mode 100644 index 0000000..a63a9bf --- /dev/null +++ b/developers/ixo-blockchain/entity/spec/05_params.md @@ -0,0 +1,9 @@ +# Parameters + +The entity module contains the following parameter: + +| **Key** | **Type** | **Description** | +| :----------------- | :------- | :--------------------------------------------------------------------------------------- | +| NftContractAddress | `string` | The cw721 smart contract address that is used to mint every entity as an nft on creation | +| NftContractMinter | `string` | The address of the `NftContractAddress` minter | +| CreateSequence | `uint64` | An onchain sequence that is used to generate the entity id so it can be deterministic | diff --git a/developers/ixo-blockchain/entity/spec/06_future_improvements.md b/developers/ixo-blockchain/entity/spec/06_future_improvements.md new file mode 100644 index 0000000..e482f6d --- /dev/null +++ b/developers/ixo-blockchain/entity/spec/06_future_improvements.md @@ -0,0 +1,5 @@ +# Future Improvements + +As the decentralized landscape evolves, we're committed to enhancing the capabilities and functionalities of the `Entity` module. Future updates may include more granular metadata management, streamlined integration with external platforms, and expanded utility in decentralized finance and applications. + +We welcome community contributions and feedback to make the `Entity` module even more robust and versatile. diff --git a/developers/ixo-blockchain/entity/spec/README.md b/developers/ixo-blockchain/entity/spec/README.md new file mode 100644 index 0000000..30494a9 --- /dev/null +++ b/developers/ixo-blockchain/entity/spec/README.md @@ -0,0 +1,51 @@ +# Entity module specification + +This document specifies the entity module, a custom Ixo Cosmos SDK module. + +The Entity Module introduces a holistic approach to NFT-backed identities, bridging the gap between decentralized identifiers and tangible assets. Upon entity creation, a symbiotic relationship forms between an IID Document, an NFT, and the Entity's metadata. Further enriched with the concept of Entity Accounts, this module ensures a seamless transition of ownership, while offering a robust framework for entities to operate within a decentralized landscape. + +## Contents + +1. **[Concepts](01_concepts.md)** + + - [Entity Module](01_concepts.md#entity-module) + - [Overview](01_concepts.md#overview) + - [Key Components](01_concepts.md#key-components) + - [Entity Data Structure](01_concepts.md#entity-data-structure) + - [Entity Accounts](01_concepts.md#entity-accounts) + - [NFT Creation](01_concepts.md#nft-creation) + - [IID Document Creation](01_concepts.md#iid-document-creation) + - [Advantages](01_concepts.md#advantages) + +2. **[State](02_state.md)** + + - [State](02_state.md#state) + - [Entities](02_state.md#entities) + - [Types](02_state.md#types) + - [Entity](02_state.md#entity) + - [EntityAccount](02_state.md#entityaccount) + - [EntityMetadata](02_state.md#entitymetadata) + +3. **[Messages](03_messages.md)** + + - [Messages](03_messages.md#messages) + - [MsgCreateEntity](03_messages.md#msgcreateentity) + - [MsgUpdateEntity](03_messages.md#msgupdateentity) + - [MsgUpdateEntityVerified](03_messages.md#msgupdateentityverified) + - [MsgTransferEntity](03_messages.md#msgtransferentity) + - [MsgCreateEntityAccount](03_messages.md#msgcreateentityaccount) + - [MsgGrantEntityAccountAuthz](03_messages.md#msggrantentityaccountauthz) + +4. **[Events](04_events.md)** + + - [Events](04_events.md#events) + - [EntityCreatedEvent](04_events.md#entitycreatedevent) + - [EntityUpdatedEvent](04_events.md#entityupdatedevent) + - [EntityVerifiedUpdatedEvent](04_events.md#entityverifiedupdatedevent) + - [EntityTransferredEvent](04_events.md#entitytransferredevent) + - [EntityAccountCreatedEvent](04_events.md#entityaccountcreatedevent) + - [EntityAccountAuthzCreatedEvent](04_events.md#entityaccountauthzcreatedevent) + +5. **[Parameters](05_params.md)** + +6. **[Future Improvements](06_future_improvements.md)** diff --git a/developers/ixo-blockchain/iid/spec/01_concepts.md b/developers/ixo-blockchain/iid/spec/01_concepts.md new file mode 100644 index 0000000..bf82bbd --- /dev/null +++ b/developers/ixo-blockchain/iid/spec/01_concepts.md @@ -0,0 +1,106 @@ +# Concepts + +## DID Documents + +A DID (Decentralized Identifier) Document is a standardized format that describes how to reach a DID subject. This format is inherently decentralized, meaning it isn't dependent on a centralized authority or a single point of failure. + +### Key Components of DID Documents: + +- **DID Subject:** The entity that the DID Document describes. It is identified by the DID itself. +- **Public Keys:** Used for authenticating the DID subject and, in some cases, for recovering lost or compromised DIDs. +- **Authentication Methods:** Specify the mechanisms that can be used to authenticate as the DID subject. +- **Service Endpoints:** These enable the discovery of services that can be utilized to interact with the DID subject or associated entities. + +DID Documents in our system also adhere to the JSON-LD (JSON Linked Data) protocols, which allow data interchange and integration of linked data using JSON. JSON-LD ensures a standardized, extensible, and context-aware representation of data in JSON format. + +### Advantages: + +- **Decentralization:** DID Documents leverage decentralized systems, negating the vulnerabilities of central points of failure. +- **Interoperability:** Their standardized format ensures DID Documents can be consistently interpreted across varying systems and platforms. +- **Security and Privacy:** Their decentralized nature guarantees users retain full control over their identifiers, freeing them from reliance on potentially vulnerable centralized systems. + +For a comprehensive understanding and detailed specifications of DID Documents, refer to the official [W3C DID specification](https://www.w3.org/TR/did-core/). For specifics on JSON-LD, consult the [W3C JSON-LD specification](https://www.w3.org/TR/json-ld/). + +![DID-Document](./assets/did_doc.svg) + +# IID Module + +
+ +
+ +