diff --git a/.gitbook/assets/image (129).png b/.gitbook/assets/image (129).png new file mode 100644 index 0000000..cd87d3c Binary files /dev/null and b/.gitbook/assets/image (129).png differ diff --git a/.gitbook/assets/image (130).png b/.gitbook/assets/image (130).png new file mode 100644 index 0000000..b0a71d7 Binary files /dev/null and b/.gitbook/assets/image (130).png differ diff --git a/.gitbook/assets/image (131).png b/.gitbook/assets/image (131).png new file mode 100644 index 0000000..affe810 Binary files /dev/null and b/.gitbook/assets/image (131).png differ diff --git a/.gitbook/assets/image (132).png b/.gitbook/assets/image (132).png new file mode 100644 index 0000000..9d83236 Binary files /dev/null and b/.gitbook/assets/image (132).png differ diff --git a/.gitbook/assets/image (133).png b/.gitbook/assets/image (133).png new file mode 100644 index 0000000..15b457a Binary files /dev/null and b/.gitbook/assets/image (133).png differ diff --git a/.gitbook/assets/image (134).png b/.gitbook/assets/image (134).png new file mode 100644 index 0000000..01c24b2 Binary files /dev/null and b/.gitbook/assets/image (134).png differ diff --git a/.gitbook/assets/image (135).png b/.gitbook/assets/image (135).png new file mode 100644 index 0000000..a2ea5b6 Binary files /dev/null and b/.gitbook/assets/image (135).png differ diff --git a/.gitbook/assets/image (136).png b/.gitbook/assets/image (136).png new file mode 100644 index 0000000..a2f3a30 Binary files /dev/null and b/.gitbook/assets/image (136).png differ diff --git a/.gitbook/assets/image (137).png b/.gitbook/assets/image (137).png new file mode 100644 index 0000000..b2ba42b Binary files /dev/null and b/.gitbook/assets/image (137).png differ diff --git a/.gitbook/assets/image (138).png b/.gitbook/assets/image (138).png new file mode 100644 index 0000000..a479115 Binary files /dev/null and b/.gitbook/assets/image (138).png differ diff --git a/.gitbook/assets/image (139).png b/.gitbook/assets/image (139).png new file mode 100644 index 0000000..ef4ccb5 Binary files /dev/null and b/.gitbook/assets/image (139).png differ diff --git a/.gitbook/assets/image (140).png b/.gitbook/assets/image (140).png new file mode 100644 index 0000000..db8e108 Binary files /dev/null and b/.gitbook/assets/image (140).png differ diff --git a/.gitbook/assets/image (141).png b/.gitbook/assets/image (141).png new file mode 100644 index 0000000..4525b2c Binary files /dev/null and b/.gitbook/assets/image (141).png differ diff --git a/.gitbook/assets/image (142).png b/.gitbook/assets/image (142).png new file mode 100644 index 0000000..c0c767e Binary files /dev/null and b/.gitbook/assets/image (142).png differ diff --git a/.gitbook/assets/image (143).png b/.gitbook/assets/image (143).png new file mode 100644 index 0000000..1898d6b Binary files /dev/null and b/.gitbook/assets/image (143).png differ diff --git a/.gitbook/assets/image (144).png b/.gitbook/assets/image (144).png new file mode 100644 index 0000000..b5d9940 Binary files /dev/null and b/.gitbook/assets/image (144).png differ diff --git a/.gitbook/assets/image (145).png b/.gitbook/assets/image (145).png new file mode 100644 index 0000000..c6ddc98 Binary files /dev/null and b/.gitbook/assets/image (145).png differ diff --git a/.gitbook/assets/image (146).png b/.gitbook/assets/image (146).png new file mode 100644 index 0000000..f765aff Binary files /dev/null and b/.gitbook/assets/image (146).png differ diff --git a/.gitbook/assets/image (147).png b/.gitbook/assets/image (147).png new file mode 100644 index 0000000..4484038 Binary files /dev/null and b/.gitbook/assets/image (147).png differ diff --git a/.gitbook/assets/image (148).png b/.gitbook/assets/image (148).png new file mode 100644 index 0000000..aab245f Binary files /dev/null and b/.gitbook/assets/image (148).png differ diff --git a/.gitbook/assets/image (149).png b/.gitbook/assets/image (149).png new file mode 100644 index 0000000..37b9a23 Binary files /dev/null and b/.gitbook/assets/image (149).png differ diff --git a/.gitbook/assets/image (150).png b/.gitbook/assets/image (150).png new file mode 100644 index 0000000..f5e3ddd Binary files /dev/null and b/.gitbook/assets/image (150).png differ diff --git a/.gitbook/assets/image (151).png b/.gitbook/assets/image (151).png new file mode 100644 index 0000000..da33320 Binary files /dev/null and b/.gitbook/assets/image (151).png differ diff --git a/.gitbook/assets/image (152).png b/.gitbook/assets/image (152).png new file mode 100644 index 0000000..5444ca5 Binary files /dev/null and b/.gitbook/assets/image (152).png differ diff --git a/.gitbook/assets/image (153).png b/.gitbook/assets/image (153).png new file mode 100644 index 0000000..9f4a0e3 Binary files /dev/null and b/.gitbook/assets/image (153).png differ diff --git a/.gitbook/assets/image (154).png b/.gitbook/assets/image (154).png new file mode 100644 index 0000000..3438dcf Binary files /dev/null and b/.gitbook/assets/image (154).png differ diff --git a/.gitbook/assets/image (155).png b/.gitbook/assets/image (155).png new file mode 100644 index 0000000..2815339 Binary files /dev/null and b/.gitbook/assets/image (155).png differ diff --git a/.gitbook/assets/image (156).png b/.gitbook/assets/image (156).png new file mode 100644 index 0000000..3c90f83 Binary files /dev/null and b/.gitbook/assets/image (156).png differ diff --git a/.gitbook/assets/image (157).png b/.gitbook/assets/image (157).png new file mode 100644 index 0000000..f7b0e7b Binary files /dev/null and b/.gitbook/assets/image (157).png differ diff --git a/.gitbook/assets/image (158).png b/.gitbook/assets/image (158).png new file mode 100644 index 0000000..be6502c Binary files /dev/null and b/.gitbook/assets/image (158).png differ diff --git a/.gitbook/assets/image (159).png b/.gitbook/assets/image (159).png new file mode 100644 index 0000000..1904cb0 Binary files /dev/null and b/.gitbook/assets/image (159).png differ diff --git a/.gitbook/assets/image (160).png b/.gitbook/assets/image (160).png new file mode 100644 index 0000000..d42b256 Binary files /dev/null and b/.gitbook/assets/image (160).png differ diff --git a/.gitbook/assets/image (161).png b/.gitbook/assets/image (161).png new file mode 100644 index 0000000..ca77ab3 Binary files /dev/null and b/.gitbook/assets/image (161).png differ diff --git a/.gitbook/assets/image (162).png b/.gitbook/assets/image (162).png new file mode 100644 index 0000000..054a837 Binary files /dev/null and b/.gitbook/assets/image (162).png differ diff --git a/.gitbook/assets/image (163).png b/.gitbook/assets/image (163).png new file mode 100644 index 0000000..a824b75 Binary files /dev/null and b/.gitbook/assets/image (163).png differ diff --git a/.gitbook/assets/image (164).png b/.gitbook/assets/image (164).png new file mode 100644 index 0000000..18ce554 Binary files /dev/null and b/.gitbook/assets/image (164).png differ diff --git a/.gitbook/assets/image (165).png b/.gitbook/assets/image (165).png new file mode 100644 index 0000000..2a876b2 Binary files /dev/null and b/.gitbook/assets/image (165).png differ diff --git a/.gitbook/assets/image (166).png b/.gitbook/assets/image (166).png new file mode 100644 index 0000000..a77571c Binary files /dev/null and b/.gitbook/assets/image (166).png differ diff --git a/.gitbook/assets/image (167).png b/.gitbook/assets/image (167).png new file mode 100644 index 0000000..918e9cd Binary files /dev/null and b/.gitbook/assets/image (167).png differ diff --git a/.gitbook/assets/image (168).png b/.gitbook/assets/image (168).png new file mode 100644 index 0000000..42931eb Binary files /dev/null and b/.gitbook/assets/image (168).png differ diff --git a/.gitbook/assets/image (169).png b/.gitbook/assets/image (169).png new file mode 100644 index 0000000..f013af2 Binary files /dev/null and b/.gitbook/assets/image (169).png differ diff --git a/.gitbook/assets/image (170).png b/.gitbook/assets/image (170).png new file mode 100644 index 0000000..345275c Binary files /dev/null and b/.gitbook/assets/image (170).png differ diff --git a/.gitbook/assets/image (171).png b/.gitbook/assets/image (171).png new file mode 100644 index 0000000..99490b4 Binary files /dev/null and b/.gitbook/assets/image (171).png differ diff --git a/.gitbook/assets/image (172).png b/.gitbook/assets/image (172).png new file mode 100644 index 0000000..41a87a8 Binary files /dev/null and b/.gitbook/assets/image (172).png differ diff --git a/.gitbook/assets/image (173).png b/.gitbook/assets/image (173).png new file mode 100644 index 0000000..25a386b Binary files /dev/null and b/.gitbook/assets/image (173).png differ diff --git a/.gitbook/assets/image (174).png b/.gitbook/assets/image (174).png new file mode 100644 index 0000000..466c484 Binary files /dev/null and b/.gitbook/assets/image (174).png differ diff --git a/.gitbook/assets/image (175).png b/.gitbook/assets/image (175).png new file mode 100644 index 0000000..57a1252 Binary files /dev/null and b/.gitbook/assets/image (175).png differ diff --git a/.gitbook/assets/image (176).png b/.gitbook/assets/image (176).png new file mode 100644 index 0000000..efd5e8b Binary files /dev/null and b/.gitbook/assets/image (176).png differ diff --git a/.gitbook/assets/image (177).png b/.gitbook/assets/image (177).png new file mode 100644 index 0000000..836fb47 Binary files /dev/null and b/.gitbook/assets/image (177).png differ diff --git a/.gitbook/assets/image (178).png b/.gitbook/assets/image (178).png new file mode 100644 index 0000000..cadbb37 Binary files /dev/null and b/.gitbook/assets/image (178).png differ diff --git a/.gitbook/assets/image (179).png b/.gitbook/assets/image (179).png new file mode 100644 index 0000000..2702e71 Binary files /dev/null and b/.gitbook/assets/image (179).png differ diff --git a/.gitbook/assets/image (180).png b/.gitbook/assets/image (180).png new file mode 100644 index 0000000..85bde6a Binary files /dev/null and b/.gitbook/assets/image (180).png differ diff --git a/.gitbook/assets/image (181).png b/.gitbook/assets/image (181).png new file mode 100644 index 0000000..dd44bff Binary files /dev/null and b/.gitbook/assets/image (181).png differ diff --git a/.gitbook/assets/image (182).png b/.gitbook/assets/image (182).png new file mode 100644 index 0000000..8298040 Binary files /dev/null and b/.gitbook/assets/image (182).png differ diff --git a/.gitbook/assets/image (183).png b/.gitbook/assets/image (183).png new file mode 100644 index 0000000..58856e3 Binary files /dev/null and b/.gitbook/assets/image (183).png differ diff --git a/.gitbook/assets/image (184).png b/.gitbook/assets/image (184).png new file mode 100644 index 0000000..4a666f9 Binary files /dev/null and b/.gitbook/assets/image (184).png differ diff --git a/.gitbook/assets/image (185).png b/.gitbook/assets/image (185).png new file mode 100644 index 0000000..da3804b Binary files /dev/null and b/.gitbook/assets/image (185).png differ diff --git a/.gitbook/assets/image (186).png b/.gitbook/assets/image (186).png new file mode 100644 index 0000000..c752102 Binary files /dev/null and b/.gitbook/assets/image (186).png differ diff --git a/.gitbook/assets/image (187).png b/.gitbook/assets/image (187).png new file mode 100644 index 0000000..895c33d Binary files /dev/null and b/.gitbook/assets/image (187).png differ diff --git a/.gitbook/assets/image (188).png b/.gitbook/assets/image (188).png new file mode 100644 index 0000000..5ae570b Binary files /dev/null and b/.gitbook/assets/image (188).png differ diff --git a/.gitbook/assets/image (189).png b/.gitbook/assets/image (189).png new file mode 100644 index 0000000..ae4d164 Binary files /dev/null and b/.gitbook/assets/image (189).png differ diff --git a/.gitbook/assets/image (190).png b/.gitbook/assets/image (190).png new file mode 100644 index 0000000..12de665 Binary files /dev/null and b/.gitbook/assets/image (190).png differ diff --git a/.gitbook/assets/image (191).png b/.gitbook/assets/image (191).png new file mode 100644 index 0000000..3e50f72 Binary files /dev/null and b/.gitbook/assets/image (191).png differ diff --git a/.gitbook/assets/image (192).png b/.gitbook/assets/image (192).png new file mode 100644 index 0000000..3b20c9f Binary files /dev/null and b/.gitbook/assets/image (192).png differ diff --git a/.gitbook/assets/image (193).png b/.gitbook/assets/image (193).png new file mode 100644 index 0000000..f6d33b5 Binary files /dev/null and b/.gitbook/assets/image (193).png differ diff --git a/.gitbook/assets/image (194).png b/.gitbook/assets/image (194).png new file mode 100644 index 0000000..e89fc24 Binary files /dev/null and b/.gitbook/assets/image (194).png differ diff --git a/.gitbook/assets/image (195).png b/.gitbook/assets/image (195).png new file mode 100644 index 0000000..9779249 Binary files /dev/null and b/.gitbook/assets/image (195).png differ diff --git a/.gitbook/assets/image (196).png b/.gitbook/assets/image (196).png new file mode 100644 index 0000000..2906752 Binary files /dev/null and b/.gitbook/assets/image (196).png differ diff --git a/.gitbook/assets/image (197).png b/.gitbook/assets/image (197).png new file mode 100644 index 0000000..c3b36e1 Binary files /dev/null and b/.gitbook/assets/image (197).png differ diff --git a/.gitbook/assets/image (198).png b/.gitbook/assets/image (198).png new file mode 100644 index 0000000..d979aed Binary files /dev/null and b/.gitbook/assets/image (198).png differ diff --git a/.gitbook/assets/image (199).png b/.gitbook/assets/image (199).png new file mode 100644 index 0000000..960dcf8 Binary files /dev/null and b/.gitbook/assets/image (199).png differ diff --git a/.gitbook/assets/image (200).png b/.gitbook/assets/image (200).png new file mode 100644 index 0000000..f369fde Binary files /dev/null and b/.gitbook/assets/image (200).png differ diff --git a/.gitbook/assets/image (201).png b/.gitbook/assets/image (201).png new file mode 100644 index 0000000..094486d Binary files /dev/null and b/.gitbook/assets/image (201).png differ diff --git a/.gitbook/assets/image (202).png b/.gitbook/assets/image (202).png new file mode 100644 index 0000000..928d188 Binary files /dev/null and b/.gitbook/assets/image (202).png differ diff --git a/.gitbook/assets/image (203).png b/.gitbook/assets/image (203).png new file mode 100644 index 0000000..e8f9778 Binary files /dev/null and b/.gitbook/assets/image (203).png differ diff --git a/.gitbook/assets/image (204).png b/.gitbook/assets/image (204).png new file mode 100644 index 0000000..345c32d Binary files /dev/null and b/.gitbook/assets/image (204).png differ diff --git a/.gitbook/assets/image (205).png b/.gitbook/assets/image (205).png new file mode 100644 index 0000000..e1df18f Binary files /dev/null and b/.gitbook/assets/image (205).png differ diff --git a/.gitbook/assets/image (206).png b/.gitbook/assets/image (206).png new file mode 100644 index 0000000..b318f6e Binary files /dev/null and b/.gitbook/assets/image (206).png differ diff --git a/.gitbook/assets/image (207).png b/.gitbook/assets/image (207).png new file mode 100644 index 0000000..92f6747 Binary files /dev/null and b/.gitbook/assets/image (207).png differ diff --git a/.gitbook/assets/image (208).png b/.gitbook/assets/image (208).png new file mode 100644 index 0000000..830029e Binary files /dev/null and b/.gitbook/assets/image (208).png differ diff --git a/.gitbook/assets/image (209).png b/.gitbook/assets/image (209).png new file mode 100644 index 0000000..09c7636 Binary files /dev/null and b/.gitbook/assets/image (209).png differ diff --git a/.gitbook/assets/image (210).png b/.gitbook/assets/image (210).png new file mode 100644 index 0000000..a8442ca Binary files /dev/null and b/.gitbook/assets/image (210).png differ diff --git a/.gitbook/assets/image (211).png b/.gitbook/assets/image (211).png new file mode 100644 index 0000000..9f4a0e3 Binary files /dev/null and b/.gitbook/assets/image (211).png differ diff --git a/.gitbook/assets/image (212).png b/.gitbook/assets/image (212).png new file mode 100644 index 0000000..b3cf774 Binary files /dev/null and b/.gitbook/assets/image (212).png differ diff --git a/.gitbook/assets/image (213).png b/.gitbook/assets/image (213).png new file mode 100644 index 0000000..055ada3 Binary files /dev/null and b/.gitbook/assets/image (213).png differ diff --git a/.gitbook/assets/image (214).png b/.gitbook/assets/image (214).png new file mode 100644 index 0000000..3ee345a Binary files /dev/null and b/.gitbook/assets/image (214).png differ diff --git a/.gitbook/assets/image (215).png b/.gitbook/assets/image (215).png new file mode 100644 index 0000000..8e55f8a Binary files /dev/null and b/.gitbook/assets/image (215).png differ diff --git a/.gitbook/assets/image (216).png b/.gitbook/assets/image (216).png new file mode 100644 index 0000000..4781192 Binary files /dev/null and b/.gitbook/assets/image (216).png differ diff --git a/README.md b/README.md index f687eef..ed295c4 100644 --- a/README.md +++ b/README.md @@ -10,13 +10,15 @@ Welcome to the Mirror documentation site. The minting of mAssets is decentralized and is undertaken by users throughout the network by opening a position and depositing collateral. Mirror ensures that there is always sufficient collateral within the protocol to cover mAssets, and also manages markets for mAssets by listing them on [Terraswap](protocol/terraswap.md) against UST. -The [Mirror Token \(MIR\)](protocol/mirror-token-mir.md) is minted by the protocol and distributed as a reward to reinforce behavior that secures the ecosystem. With it, Mirror ensures liquid mAsset markets by rewarding MIR to users who stake [LP Tokens](protocol/lp-token.md) obtained through providing liquidity. MIR is valuable as it is can be staked to receive voting privileges and to earn a share of the protocol's CDP withdrawal fees. +The [Mirror Token \(MIR\)](protocol/mirror-token-mir.md) is minted by the protocol and distributed as a reward to reinforce behavior that secures the ecosystem. With it, Mirror ensures liquid mAsset markets by rewarding MIR to users who stake [LP Tokens](protocol/staking-tokens-lp-and-slp.md#lp-tokens) obtained through providing liquidity. Also to incentivize users to ensure mAssets to mimic the price behavior of real-world assets, users who stake sLP Tokens obtained through shorting mAssets are rewarded with MIR.MIR is valuable as it is can be staked to receive voting privileges and to earn a share of the protocol's CDP withdrawal fees. Mirror is a project developed and steered by its community: its markets are maintained by its own users through MIR incentives, and the protocol evolves with new ideas through democratic [governance](protocol/governance/). ## Learn More -* Read the [whitepaper](https://docsend.com/view/kcsm42mqiyu5t6ej) +* Read the whitepaper + * [Version 1](https://docsend.com/view/kcsm42mqiyu5t6ej) + * [Version 2](https://mirror.finance/Mirror_Protocol_v2.pdf) * Understand the [protocol](protocol/synopsis.md) * Read the[ core smart contracts](contracts/architecture.md) diff --git a/SUMMARY.md b/SUMMARY.md index 563ae3c..61b365e 100644 --- a/SUMMARY.md +++ b/SUMMARY.md @@ -1,6 +1,7 @@ # Table of contents * [Home](README.md) +* [What's new for Mirror v2?](whats-new-for-mirror-v2.md) * [Interchain Access](networks.md) * [Security](security.md) * [FAQ](faq.md) @@ -11,10 +12,12 @@ * [Mirrored Assets \(mAssets\)](protocol/mirrored-assets-massets.md) * [Mirror Token \(MIR\)](protocol/mirror-token-mir.md) * [Terraswap](protocol/terraswap.md) -* [LP Tokens](protocol/lp-token.md) +* [Staking Tokens \(LP & sLP\)](protocol/staking-tokens-lp-and-slp.md) * [Governance](protocol/governance/README.md) * [Proposal Types](protocol/governance/proposal-types.md) * [Whitelist Procedure](protocol/governance/whitelist-procedure.md) + * [Delist Procedure](protocol/governance/delist-procedure.md) + * [Pre-IPO Procedure](protocol/governance/pre-ipo-procedure.md) * [Modify Mint Parameters](protocol/governance/modify-mint-parameters.md) * [Modify Gov Parameters](protocol/governance/modify-gov-parameters.md) * [Community Grants](protocol/governance/community-grants.md) @@ -31,10 +34,10 @@ * [Web App](user-guide/getting-started/README.md) * [Sending Tokens](user-guide/getting-started/sending-tokens.md) * [Trade](user-guide/getting-started/trade.md) - * [Mint](user-guide/getting-started/mint-and-burn.md) - * [Pool](user-guide/getting-started/pool.md) - * [Stake](user-guide/getting-started/stake.md) + * [Borrow](user-guide/getting-started/mint-and-burn.md) + * [Farm](user-guide/getting-started/pool.md) * [Governance](user-guide/getting-started/governance.md) + * [Claim MIR Reward](user-guide/getting-started/claim-mir-reward.md) * [Mirror on Ethereum](user-guide/meth-dual-yield/README.md) * [Sending Tokens](user-guide/meth-dual-yield/sending-tokens.md) * [Trade](user-guide/meth-dual-yield/trade.md) @@ -49,7 +52,9 @@ * [Factory](contracts/factory.md) * [Gov](contracts/gov.md) * [Mint](contracts/mint.md) +* [Lock](contracts/lock.md) * [Oracle](contracts/oracle.md) +* [Collateral Oracle](contracts/collateral-oracle.md) * [Staking](contracts/staking.md) * [Limit Order](contracts/limit-order.md) diff --git a/contracts/architecture.md b/contracts/architecture.md index 61e91b6..e7b7a5a 100644 --- a/contracts/architecture.md +++ b/contracts/architecture.md @@ -2,8 +2,8 @@ This section describes provides a high-level overview regarding the technical implementation of Mirror Protocol. -{% hint style="warning" %} -Even with a thorough understanding of Mirror Protocol, it is highly recommended to interact with Mirror through client channels such as the Mirror Web App or Mirror.js. +{% hint style="info" %} +Even with a thorough understanding of Mirror Protocol, it is highly recommended to interact with Mirror through client channels such as the [Mirror Web App](../user-guide/getting-started/) or [Mirror.js.](../developer-tools/mirror.js.md) {% endhint %} ## Smart Contracts @@ -22,7 +22,7 @@ The source code for Mirror smart contracts can be found on [GitHub](https://gith Collector Gathers protocol fees incurred from CDP withdrawals and liquidations and - sends to Gov + send to Gov Community @@ -39,23 +39,39 @@ The source code for Mirror smart contracts can be found on [GitHub](https://gith

Allows other Mirror contracts to be controlled by decentralized governance

-

Distributes MIR received from Collector to MIR stakers

+

Distributes MIR received from Collector to MIR stakers and voters

Mint - Handles CDP creation, management and liquidation + Handles both long and short CDP creation, management, and liquidation + + + Lock + + Responsible for locking up UST from short CDP Oracle - Provides interface for oracle feeders to post prices for mAssets + Provides an interface for oracle feeders to post prices for mAssets + + + Collateral Oracle + + Feeds price and collateral multiplier for each collateral asset + type Staking - Distributes MIR rewards from block reward to LP stakers + Distributes MIR rewards from block reward to LP and sLP stakers + + + Limit Order + + Registers and executes swap orders at submitted limit price and amount @@ -67,4 +83,5 @@ When new mAssets are whitelisted, Mirror Protocol will create the following cont * Terraswap CW20 Token for the new mAsset * Terraswap Pair for the new mAsset against UST * Terraswap CW20 Token for the new mAsset's LP Token +* Terraswap CW20 Token for the new mAsset's sLP Token diff --git a/contracts/collateral-oracle.md b/contracts/collateral-oracle.md new file mode 100644 index 0000000..8181c71 --- /dev/null +++ b/contracts/collateral-oracle.md @@ -0,0 +1,606 @@ +# Collateral Oracle + +Collateral Oracle contract is responsible for registering a new type of collateral to be used in Mirror Mint contract for CDP creation and reporting its price. Oracle feeders that are connected to the contract keep the collateral prices up-to-date with continuous price quote updates that are fetched from their reputable sources. + +## InitMsg + +{% tabs %} +{% tab title="Rust" %} +```rust +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] +pub struct InitMsg { + pub owner: HumanAddr, + pub mint_contract: HumanAddr, + pub base_denom: String, + pub mirror_oracle: HumanAddr, + pub anchor_oracle: HumanAddr, + pub band_oracle: HumanAddr, +} +``` +{% endtab %} +{% endtabs %} + +| Key | Type | Description | +| :--- | :--- | :--- | +| `owner` | HumanAddr | Address of owner | +| `mint_contract` | HumanAddr | Address of Mirror Mint contract | +| `base_denom` | String | Asset in which prices will be denominated in \(default TerraUSD\) | +| `mirror_oracle` | HumanAddr | Address of MIR token oracle feeder | +| `anchor_oracle` | HumanAddr | Address of ANC token oracle feeder | +| `band_oracle` | HumanAddr | Address of Band Protocol oracle feeder | + +## HandleMsg + +### `UpdateConfig` + +This function can be only issued by the active owner of the Collateral Oracle contract. Changes the configuration of collateral oracle contract. + +{% tabs %} +{% tab title="Rust" %} +```rust +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] +#[serde(rename_all = "snake_case")] +pub enum HandleMsg { + UpdateConfig { + owner: Option, + mint_contract: Option, + base_denom: Option, + mirror_oracle: Option, + anchor_oracle: Option, + band_oracle: Option, + }, +} +``` +{% endtab %} + +{% tab title="JSON" %} +```javascript +{ + "update_config": { + "owner": "terra1...", + "mint_contract": "terra1...", + "base_denom": "uusd", + "mirror_oracle": "terra1...", + "anchor_oracle": "terra1...", + "band_oracle": "terra1..." + } +} +``` +{% endtab %} +{% endtabs %} + +| Key | Type | Description | +| :--- | :--- | :--- | +| `owner`\* | HumanAddr | Address of owner | +| `mint_contract`\* | HumanAddr | Address of Mirror Mint contract | +| `base_denom`\* | String | Asset in which prices will be denominated in \(default TerraUSD\) | +| `mirror_oracle`\* | HumanAddr | Address of MIR token oracle feeder | +| `anchor_oracle`\* | HumanAddr | Address of ANC token oracle feeder | +| `band_oracle`\* | HumanAddr | Address of Band Protocol oracle feeder | + +\*= optional + +### `RegisterCollateralAsset` + +Registers a new type of collateral to be used on Mirror Mint contract for the creation of new CDP. Can only be issued by the owner of Collateral Oracle. + +{% tabs %} +{% tab title="Rust" %} +```rust +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] +#[serde(rename_all = "snake_case")] +pub enum HandleMsg { + RegisterCollateralAsset { + asset: AssetInfo, + price_source: SourceType, + multiplier: Decimal, + }, +} +``` +{% endtab %} + +{% tab title="JSON" %} +```javascript +{ + "register_collateral_asset": { + "asset": { + "token": { + "contract_addr": "terra1..." + } + }, + "price_source": { + "terra_oracle": { + "terra_oracle_query": "eyAiZXhlY3V0ZV9tc2ciOiAiYmxhaCBibGFoIiB9" + }, + "band_oracle": { + "band_oracle_query": "eyAiZXhlY3V0ZV9tc2ciOiAiYmxhaCBibGFoIiB9" + }, + "fixed_price": { + "price": "123.123456" + }, + "terraswap": { + "terraswap_query": "eyAiZXhlY3V0ZV9tc2ciOiAiYmxhaCBibGFoIiB9", + "intermediate_denom": "uluna" + }, + "anchor_market": { + "anchor_market_query": "eyAiZXhlY3V0ZV9tc2ciOiAiYmxhaCBibGFoIiB9" + }, + "native": { + "native_denom": "uusd" + } + } + "multiplier": "0.05" + } +} +``` +{% endtab %} +{% endtabs %} + +| Key | Type | Description | +| :--- | :--- | :--- | +| `asset` | AssetInfo | Asset to be registered | +| `price_source` | SourceType | Base64-encoded string of JSON of Receive Hook | +| `multiplier` | Decimal | Multiplied to `min_collateral_ratio` when this asset is chosen as collateral | + +#### `SourceType` + +```rust +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] +#[serde(rename_all = "snake_case")] +pub enum SourceType { + TerraOracle { + terra_oracle_query: Binary, + }, + BandOracle { + band_oracle_query: Binary, + }, + FixedPrice { + price: Decimal, + }, + Terraswap { + terraswap_query: Binary, + intermediate_denom: Option, + }, + AnchorMarket { + anchor_market_query: Binary, + }, + Native { + native_denom: String, + }, +} +``` + +| Key | Type | Description | +| :--- | :--- | :--- | +| `terra_oracle_query` | Binary | Queries information of Terra's oracle | +| `band_oracle_query` | Binary | Queries information of Band Protocol oracle | +| `price` | Decimal | Fixed price to be used for the collateral type \(aUST = 1 UST\) | +| `terraswap_query` | Binary | Queries information of Terraswap Pair | +| `intermediate_denom`\* | String | Used to calculate UST denominated price of an asset when the asset does not have UST pair pool | +| `anchor_market_query` | Binary | Query to fetch information for Anchor Protocol's asset information \(ANC\) | +| `native_denom` | String | String denomination of the Terra native asset \(uusd\) | + +### `RevokeCollateralAsset` + +Removes registered collateral so that it is no longer used as collateral for Mirror Mint. Can only be issued by the owner of Collateral Oracle. + +{% tabs %} +{% tab title="Rust" %} +```rust +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] +#[serde(rename_all = "snake_case")] +pub enum HandleMsg { + RevokeCollateralAsset { + asset: AssetInfo, + }, +} +``` +{% endtab %} + +{% tab title="JSON" %} +```javascript +{ + "revote_collateral_asset": { + "asset": { + "token": { + "contract_addr": "terra1..." + } + } + } +} +``` +{% endtab %} +{% endtabs %} + +| Key | Type | Description | +| :--- | :--- | :--- | +| `asset` | AssetInfo | Asset to be revoked | + +### `UpdateCollateralPriceSource` + +Updates the price data source for a specific collateral asset. Can only be issued by the owner of Collateral Oracle. + +{% tabs %} +{% tab title="Rust" %} +```rust +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] +#[serde(rename_all = "snake_case")] +pub enum HandleMsg { + UpdateCollateralPriceSource { + asset: AssetInfo, + price_source: SourceType, + }, +} +``` +{% endtab %} + +{% tab title="JSON" %} +```javascript +{ + "update_collateral_query": { + "asset": { + "token": { + "contract_addr": "terra1..." + } + }, + "price_source": { + "terra_oracle": { + "terra_oracle_query": "eyAiZXhlY3V0ZV9tc2ciOiAiYmxhaCBibGFoIiB9" + }, + "band_oracle": { + "band_oracle_query": "eyAiZXhlY3V0ZV9tc2ciOiAiYmxhaCBibGFoIiB9" + }, + "fixed_price": { + "price": "123.123456" + }, + "terraswap": { + "terraswap_query": "eyAiZXhlY3V0ZV9tc2ciOiAiYmxhaCBibGFoIiB9", + "intermediate_denom": "uluna" + }, + "anchor_market": { + "anchor_market_query": "eyAiZXhlY3V0ZV9tc2ciOiAiYmxhaCBibGFoIiB9" + }, + "native": { + "native_denom": "uusd" + } + } + } +} +``` +{% endtab %} +{% endtabs %} + +| Key | Type | Description | +| :--- | :--- | :--- | +| `asset` | AssetInfo | Asset to update query information | +| `price_source` | SourceType | Message detailing where to query asset information from | + +### `UpdateCollateralMultiplier` + +Updates the multiplier parameter of a specific collateral asset registered in Mirror contract. Can only be issued by the owner of Collateral Oracle. + +{% tabs %} +{% tab title="Rust" %} +```rust +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] +#[serde(rename_all = "snake_case")] +pub enum HandleMsg { + UpdateCollateralPremium { + asset: AssetInfo, + multiplier: Decimal, + }, +} +``` +{% endtab %} + +{% tab title="JSON" %} +```javascript +{ + "update_collateral_premium": { + "asset": { + "token": { + "contract_addr": "terra1..." + } + }, + "multiplier": "2.00" + } +} +``` +{% endtab %} +{% endtabs %} + +| Key | Type | Description | +| :--- | :--- | :--- | +| `asset` | AssetInfo | Asset to change collateral premium | +| `multiplier` | Decimal | Collateral ratio multiplied to `min_collateral_ratio` of the CDP being created by choosing this asset | + +## QueryMsg + +### `Config` + +Queries the configuration of Collateral Oracle. + +{% tabs %} +{% tab title="Rust" %} +```rust +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] +#[serde(rename_all = "snake_case")] + pub enum QueryMsg { + Config {}, +} +``` + +#### Response + +```rust +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] +pub struct ConfigResponse { + pub owner: HumanAddr, + pub mint_contract: HumanAddr, + pub base_denom: String, + pub mirror_oracle: HumanAddr, + pub anchor_oracle: HumanAddr, + pub band_oracle: HumanAddr, +} +``` + +| Key | Type | Description | +| :--- | :--- | :--- | +| `owner` | HumanAddr | Address of owner | +| `mint_contract` | HumanAddr | Address of Mirror Mint contract | +| `base_denom` | String | Asset in which prices will be denominated in \(default TerraUSD\) | +| `mirror_oracle` | HumanAddr | Address of MIR token oracle feeder | +| `anchor_oracle` | HumanAddr | Address of ANC token oracle feeder | +| `band_oracle` | HumanAddr | Address of Band Protocol oracle feeder | +{% endtab %} + +{% tab title="JSON" %} +```javascript +{ + "config": {} +} +``` + +#### Response + +```rust +{ + "config_response": { + "owner": "terra1...", + "mint_contract": "terra1...", + "base_denom": "uusd", + "mirror_oracle": "terra1...", + "anchor_oracle": "terra1...", + "band_oracle": "terra1..." + } +} +``` + +| Key | Type | Description | +| :--- | :--- | :--- | +| `owner` | HumanAddr | Address of owner | +| `mint_contract` | HumanAddr | Address of Mirror Mint contract | +| `base_denom` | String | Asset in which prices will be denominated in \(default TerraUSD\) | +| `mirror_oracle` | HumanAddr | Address of MIR token oracle feeder | +| `anchor_oracle` | HumanAddr | Address of ANC token oracle feeder | +| `band_oracle` | HumanAddr | Address of Band Protocol oracle feeder | +{% endtab %} +{% endtabs %} + +### `CollateralPrice` + +Returns the UST price of the selected collateral asset. + +{% tabs %} +{% tab title="Rust" %} +```rust +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] +#[serde(rename_all = "snake_case")] +pub enum QueryMsg { + CollateralPrice { + asset: String, + }, +} +``` + +| Key | Type | Description | +| :--- | :--- | :--- | +| `asset` | String | Name of the collateral asset to query prices | + +#### Response + +Returns the UST price of the selected collateral asset. + +```rust +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] +pub struct CollateralPriceResponse { + pub asset: String, + pub rate: Decimal, + pub last_updated: u64 + pub multiplier: Decimal, + pub is_revoked: bool, +} +``` + +| Key | Type | Description | +| :--- | :--- | :--- | +| `asset` | String | Name of the collateral asset to query prices | +| `rate` | Decimal | Current price of the collateral | +| `collateral_premium` | Decimal | Collateral ratio added to `min_collateral_ratio` of the CDP being created by choosing this asset | +| `is_revoked` | bool | Check if the collateral is registered or revoked | +{% endtab %} + +{% tab title="JSON" %} +```javascript +{ + "collateral_price": { + "asset": "uluna" + } +} +``` + +| Key | Type | Description | +| :--- | :--- | :--- | +| `asset` | String | Name of the collateral asset to query prices | + +#### Response + +Returns the UST price of the selected collateral asset. + +```rust +{ + "collateral_price_response": { + "asset": "uluna", + "rate": "123.456789", + "last_updated": 8 + "multiplier": "2.0", + "is_revoked": false + } +} +``` + +| Key | Type | Description | +| :--- | :--- | :--- | +| `asset` | String | Name of the collateral asset to query prices | +| `rate` | Decimal | Current price of the collateral | +| `last_updated` | Decimal | Time when the asset price was last updated | +| `multiplier` | Decimal | Collateral ratio multiplied to `min_collateral_ratio` of the CDP being created by choosing this asset | +| `is_revoked` | bool | Check if the collateral is registered or revoked | +{% endtab %} +{% endtabs %} + +### `CollateralAssetInfo` + +Returns the parameter of selected collateral. + +{% tabs %} +{% tab title="Rust" %} +```rust +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] +#[serde(rename_all = "snake_case")] +pub enum QueryMsg { + CollateralAssetInfo { + asset: String, + }, +} +``` + +| Key | Type | Description | +| :--- | :--- | :--- | +| `asset` | String | Name of the collateral asset to query prices | + +#### Response + +```rust +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] +pub struct CollateralInfoResponse { + pub asset: String, + pub multiplier: Decimal, + pub source_type: String, + pub is_revoked: bool, +} +``` + +| Key | Type | Description | +| :--- | :--- | :--- | +| `asset` | String | Name of the collateral asset to query prices | +| `collateral_premium` | Decimal | Collateral ratio added to `min_collateral_ratio` of the CDP being created by choosing this asset | +| `source_type` | WasmQuery | Queries the public API of another contract at a known address \(with known ABI\) return value is whatever the contract returns \(caller should know\) | +| `is_revoked` | bool | Check if the collateral is registered or revoked | +{% endtab %} + +{% tab title="JSON" %} +```javascript +{ + "collateral_asset_info": { + "asset": "uluna" + } +} +``` + +| Key | Type | Description | +| :--- | :--- | :--- | +| `asset` | String | Name of the collateral asset to query prices | + +#### Response + +```rust +{ + "collateral_asset_info_response": { + "asset": "uluna", + "multiplier": "2.0", + "source_type": "WasmQuery", + "is_revoked": false + } +} +``` + +| Key | Type | Description | +| :--- | :--- | :--- | +| `asset` | String | Name of the collateral asset to query prices | +| `multiplier` | Decimal | Collateral ratio multiplied to `min_collateral_ratio` of the CDP being created by choosing this asset | +| `source_type` | String | Queries the public API of another contract at a known address \(with known ABI\) return value is whatever the contract returns \(caller should know\) | +| `is_revoked` | bool | Check if the collateral is registered or revoked | +{% endtab %} +{% endtabs %} + +### `CollateralAssetInfos` + +Returns parameters for multiple collateral assets. + +{% tabs %} +{% tab title="Rust" %} +```rust +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] +#[serde(rename_all = "snake_case")] +pub enum QueryMsg { + CollateralAssetInfos {}, +} +``` + +#### Response + +```rust +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] +pub struct CollateralInfosResponse { + pub collaterals: Vec, +} +``` + +| Key | Type | Description | +| :--- | :--- | :--- | +| `collaterals` | Vec<CollateralInfoResponse> | Array of `CollateralInfoResponse` | +{% endtab %} + +{% tab title="JSON" %} +```javascript +{ + "collateral_asset_infos": {} +} +``` + +#### Response + +```rust +{ + "collateral_infos_respose": { + "collaterals": [ + [ + "asset": "uluna", + "collateral_premium": "2.0", + "query_request": "WasmQuery", + "is_revoked": false + ] + ... + } +} +``` + +| Key | Type | Description | +| :--- | :--- | :--- | +| `collaterals` | Vec<CollateralInfoResponse> | Array of `CollateralInfoResponse` | +{% endtab %} +{% endtabs %} + + + diff --git a/contracts/collector.md b/contracts/collector.md index d0fec0e..f83676d 100644 --- a/contracts/collector.md +++ b/contracts/collector.md @@ -1,6 +1,6 @@ # Collector -The Collector accumulates fee rewards generated from CDP withdrawal within the protocol, and converts them into UST in order to purchase MIR from the MIR-UST Terraswap pool. The MIR is then sent to the [Gov Contract](gov.md) to supply trading fee rewards for MIR stakers. +The Collector accumulates fee rewards generated from CDP withdrawal within the protocol, and converts them into UST in order to purchase MIR from the MIR-UST Terraswap pool. The MIR is then sent to the [Gov Contract](gov.md) to supply trading fee rewards for MIR stakers. ![](../.gitbook/assets/image.png) @@ -15,6 +15,10 @@ pub struct InitMsg { pub terraswap_factory: HumanAddr, pub mirror_token: HumanAddr, pub base_denom: String, + pub aust_token: HumanAddr, + pub anchor_market: HumanAddr, + pub bluna_token: HumanAddr, + pub bluna_swap_denom: String, } ``` {% endtab %} @@ -25,7 +29,11 @@ pub struct InitMsg { "distribution_contract": "terra1...", "terraswap_factory": "terra1...", "mirror_token": "terra1...", - "base_denom": "uusd" // native Terra token + "base_denom": "uusd", // native Terra token + "aust_token": "terra1...", //aUST params + "anchor_market": "terra1...", + "bluna_token": "terra1...", //bLuna params + "bluna_swap_denom": "uusd" } ``` {% endtab %} @@ -37,15 +45,77 @@ pub struct InitMsg { | `terraswap_factory` | HumanAddr | Contract address of Terraswap Factory | | `mirror_token` | HumanAddr | Contract address of Mirror Token \(MIR\) | | `base_denom` | String | Base denomination \(native Terra token denom\) | +| `aust_token` | HumanAddr | Address of aUST token contract | +| `anchor_market` | HumanAddr | Address of Anchor Market contract | +| `bluna_token` | HumanAddr | Address of bLuna token contract | +| `bluna_swap_denom` | String | Base denomination which bLuna to be swapped into \(uusd\) | ## HandleMsg +### UpdateConfig + +Updates the configuration of Collector contrat. Can only be called by owner. + +{% tabs %} +{% tab title="Rust" %} +```rust +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] +#[serde(rename_all = "snake_case")] +pub enum HandleMsg { + UpdateConfig { + owner: Option, + distribution_contract: Option, + terraswap_factory: Option, + mirror_token: Option, + base_denom: Option, + aust_token: Option, + anchor_market: Option, + bluna_token: Option, + bluna_swap_denom: Option, + }, +``` +{% endtab %} + +{% tab title="JSON" %} +```javascript +{ + "update_config": { + "owner": "terra1...", + "distribution_contract": "terra1...", + "terraswap_factory": "terra1...", + "mirror_token": "terra1...", + "base_denom": "uusd", // native Terra token + "aust_token": "terra1...", //aUST params + "anchor_market": "terra1...", + "bluna_token": "terra1...", //bLuna params + "bluna_swap_denom": "uusd" + } +} +``` +{% endtab %} +{% endtabs %} + +| Key | Type | Description | +| :--- | :--- | :--- | +| `owner`\* | HumanAddr | Address of the contract owner\* | +| `distribution_contract`\* | HumanAddr | Contract address of [Mirror Governance](gov.md) | +| `terraswap_factory`\* | HumanAddr | Contract address of Terraswap Factory | +| `mirror_token`\* | HumanAddr | Contract address of Mirror Token \(MIR\) | +| `base_denom`\* | String | Base denomination \(native Terra token denom\) | +| `aust_token`\* | HumanAddr | Address of aUST token contract | +| `anchor_market`\* | HumanAddr | Address of Anchor Market contract | +| `bluna_token`\* | HumanAddr | Address of bLuna token contract | +| `bluna_swap_denom`\* | String | Base denomination which bLuna to be swapped into \(uusd\) | + +\*= optional + ### `Convert` Depending on `asset_token`, performs one of the following: -* if `asset_token` is an mAsset, sells the contract's balance of that mAsset for UST on Terraswap -* if `asset_token` is the MIR token, buys MIR off the MIR/UST Terraswap pool with the contract's UST balance +* if `asset_token` is an mAsset Luna or Anchor sells the contract's balance of that mAsset for UST on Terraswap +* if `asset_token` is the UST token, buys MIR off the MIR/UST Terraswap pool with the contract's UST balance +* if `asset_token` is aUST, or bLuna sells the token based on registered `anchor_market` or `bluna_swap_denom` {% tabs %} {% tab title="Rust" %} @@ -75,9 +145,9 @@ pub enum HandleMsg { | :--- | :--- | :--- | | `asset_token` | HumanAddr | Contract address of asset to convert | -### `Send` +### `LunaSwapHook` -Sends to entire balance of collector's Mirror Tokens \(MIR\) to `distribution_contract` +Hook to swap Luna token to MIR. {% tabs %} {% tab title="Rust" %} @@ -85,7 +155,7 @@ Sends to entire balance of collector's Mirror Tokens \(MIR\) to `distribution_co #[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] #[serde(rename_all = "snake_case")] pub enum HandleMsg { - Send {} + LunaSwapHook {} } ``` {% endtab %} @@ -114,6 +184,35 @@ pub enum QueryMsg { Config {} } ``` + +#### Response + +```rust +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] +pub struct ConfigResponse { + pub owner: HumanAddr, + pub distribution_contract: HumanAddr, // collected rewards receiver + pub terraswap_factory: HumanAddr, + pub mirror_token: HumanAddr, + pub base_denom: String, + pub aust_token: HumanAddr, + pub anchor_market: HumanAddr, + pub bluna_token: HumanAddr, + pub bluna_swap_denom: String, +} +``` + +| Key | Type | Description | +| :--- | :--- | :--- | +| `owner` | HumanAddr | Address of the contract owner\* | +| `distribution_contract` | HumanAddr | Contract address of [Mirror Governance](gov.md) | +| `terraswap_factory` | HumanAddr | Contract address of Terraswap Factory | +| `mirror_token` | HumanAddr | Contract address of Mirror Token \(MIR\) | +| `base_denom` | String | Base denomination \(native Terra token denom\) | +| `aust_token` | HumanAddr | Address of aUST token contract | +| `anchor_market` | HumanAddr | Address of Anchor Market contract | +| `bluna_token` | HumanAddr | Address of bLuna token contract | +| `bluna_swap_denom` | String | Base denomination which bLuna to be swapped into \(uusd\) | {% endtab %} {% tab title="JSON" %} @@ -122,10 +221,36 @@ pub enum QueryMsg { "config": {} } ``` -{% endtab %} -{% endtabs %} + +#### Response + +```rust +{ + "config_response": { + "owner": "terra1...", + "distribution_contract": "terra1...", + "terraswap_factory": "terra1...", + "mirror_token": "terra1...", + "base_denom": "uusd", // native Terra token + "aust_token": "terra1...", //aUST params + "anchor_market": "terra1...", + "bluna_token": "terra1...", //bLuna params + "bluna_swap_denom": "uusd" + } +} +``` | Key | Type | Description | | :--- | :--- | :--- | - +| `owner` | HumanAddr | Address of the contract owner\* | +| `distribution_contract` | HumanAddr | Contract address of [Mirror Governance](gov.md) | +| `terraswap_factory` | HumanAddr | Contract address of Terraswap Factory | +| `mirror_token` | HumanAddr | Contract address of Mirror Token \(MIR\) | +| `base_denom` | String | Base denomination \(native Terra token denom\) | +| `aust_token` | HumanAddr | Address of aUST token contract | +| `anchor_market` | HumanAddr | Address of Anchor Market contract | +| `bluna_token` | HumanAddr | Address of bLuna token contract | +| `bluna_swap_denom` | String | Base denomination which bLuna to be swapped into \(uusd\) | +{% endtab %} +{% endtabs %} diff --git a/contracts/community.md b/contracts/community.md index 26b71c5..55d4b42 100644 --- a/contracts/community.md +++ b/contracts/community.md @@ -123,6 +123,23 @@ pub enum QueryMsg { } } ``` + +#### Response + +```rust +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] +pub struct ConfigResponse { + pub owner: HumanAddr, + pub mirror_token: HumanAddr, + pub spend_limit: Uint128, +} +``` + +| Key | Type | Description | +| :--- | :--- | :--- | +| `owner` | HumanAddr | Owner address | +| `mirror_token` | HumanAddr | Contract address of the Mirror Token | +| `spend_limit` | Uint128 | Max amount of disbursement | {% endtab %} {% tab title="JSON" %} @@ -131,10 +148,23 @@ pub enum QueryMsg { "config": {} } ``` -{% endtab %} -{% endtabs %} + +#### Response + +```rust +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] +pub struct ConfigResponse { + pub owner: HumanAddr, + pub mirror_token: HumanAddr, + pub spend_limit: Uint128, +} +``` | Key | Type | Description | | :--- | :--- | :--- | - +| `owner` | HumanAddr | Owner address | +| `mirror_token` | HumanAddr | Contract address of the Mirror Token | +| `spend_limit` | Uint128 | Max amount of disbursement | +{% endtab %} +{% endtabs %} diff --git a/contracts/factory.md b/contracts/factory.md index 196819a..d957558 100644 --- a/contracts/factory.md +++ b/contracts/factory.md @@ -1,6 +1,6 @@ # Factory -The Factory contract is Mirror Protocol's central directory and organizes information related to mAssets and the Mirror Token \(MIR\). It is also responsible for minting new MIR tokens each block and distributing them to the [Staking Contract](staking.md) for rewarding LP Token stakers. +The Factory contract is Mirror Protocol's central directory and organizes information related to mAssets and the Mirror Token \(MIR\). It is also responsible for minting new MIR tokens each block and distributing them to the [Staking Contract](staking.md) for rewarding LP &sLP Token stakers. After the initial bootstrapping of Mirror Protocol contracts, the Factory is assigned to be the owner for the Mint, Oracle, Staking, and Collector contracts. The Factory is owned by the [Gov Contract.](gov.md) @@ -181,6 +181,40 @@ pub enum HandleMsg { \* = optional +### `UpdateWeight` + +Updates the `weight` parameter of a specific token. + +{% tabs %} +{% tab title="Rust" %} +```rust +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] +#[serde(rename_all = "snake_case")] +pub enum HandleMsg { + UpdateWeight { + asset_token: HumanAddr, + weight: u32, + } +``` +{% endtab %} + +{% tab title="JSON" %} +```javascript +{ + "update_weight": { + "asset_token": "terra1...", + "weight": 8 + } +} +``` +{% endtab %} +{% endtabs %} + +| Name | Type | Description | +| :--- | :--- | :--- | +| `asset_token` | HumanAddr | Contract address of mAsset token | +| `weight` | u32 | Ratio of MIR token reward received by this asset in comparison to other tokens | + ### `Whitelist` Introduces a new mAsset to the protocol and creates markets on Terraswap. This process will: @@ -210,6 +244,10 @@ pub enum HandleMsg { pub struct Params { pub auction_discount: Decimal, pub min_collateral_ratio: Decimal, + pub weight: Option, + pub mint_period: Option, + pub min_collateral_ratio_after_ipo: Option, + pub pre_ipo_price: Option, } ``` {% endtab %} @@ -235,7 +273,7 @@ pub struct Params { | :--- | :--- | :--- | | `name` | String | Name of new asset to be whitelisted | | `oracle_feeder` | HumanAddr | Address of Oracle Feeder for mAsset | -| `params` | Params | mAsset parameters | +| `params` | Params | mAsset parameters to be registered | | `symbol` | String | mAsset symbol \(ex: `mAAPL`\) | #### mAsset Params @@ -244,6 +282,12 @@ pub struct Params { | :--- | :--- | :--- | | `auction_discount` | Decimal | Liquidation discount for purchasing CDP's collateral | | `min_collateral_ratio` | Decimal | Minimum C-ratio for CDPs that mint the mAsset | +| `weight`\* | u32 | Ratio of MIR token reward received by this asset in comparison to other tokens | +| `mint_period`\* | u64 | Time period after asset creation in which minting is enabled \(Seconds\) | +| `min_collateral_ratio_after_ipo`\* | Decimal | `min_collateral_ratio` to be applied to this asset after IPO | +| `pre_ipo_price`\* | Decimal | Fixed price used to mint Pre-IPO asset during `mint_period` | + +\*= optional \(Only added for [Pre-IPO asset whitelisting](../protocol/mirrored-assets-massets.md#pre-ipo)\) ### `TokenCreationHook` @@ -374,6 +418,44 @@ pub enum HandleMsg { {% endtab %} {% endtabs %} +### `RevokeAsset` + +`(Feeder Operation)` +Used when delisting occurs for a specific mAsset. + +* mAsset is unregistered from MIR reward pool +* Fixes the oracle price at `end_price` for mint contract operation + +{% tabs %} +{% tab title="Rust" %} +```rust +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] +#[serde(rename_all = "snake_case")] +pub enum HandleMsg { + RevokeAsset { + asset_token: HumanAddr, + end_price: Decimal, + } +``` +{% endtab %} + +{% tab title="JSON" %} +```javascript +{ + "revoke_asset": { + "asset_token": "terra1...", + "end_price": "123.456789" + } +} +``` +{% endtab %} +{% endtabs %} + +| Name | Type | Description | +| :--- | :--- | :--- | +| `asset_token` | HumanAddr | Contract address of mAsset token | +| `end_price` | Decimal | Final price to freeze revoked mAsset | + ### `MigrateAsset` Can be issued by the oracle feeder of an mAsset to trigger the [mAsset migration procedure](../protocol/mirrored-assets-massets.md#deprecation-and-migration). @@ -410,7 +492,7 @@ pub enum HandleMsg { | Key | Type | Description | | :--- | :--- | :--- | -| `end_price` | Decimal | Freezes the oracle price of mAsset at this value | +| `end_price` | Decimal | Freezes the oracle price of mAsset at this value \(Denominated in UST\) | | `from_token` | HumanAddr | Contract address of mAsset to migrate | | `name` | String | Name of the new asset post-migration | | `symbol` | String | Symbol for the new asset post-migration | @@ -430,6 +512,39 @@ pub enum QueryMsg { Config {} } ``` + +#### Response + +```rust +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] +pub struct ConfigResponse { + pub owner: HumanAddr, + pub mirror_token: HumanAddr, + pub mint_contract: HumanAddr, + pub staking_contract: HumanAddr, + pub commission_collector: HumanAddr, + pub oracle_contract: HumanAddr, + pub terraswap_factory: HumanAddr, + pub token_code_id: u64, + pub base_denom: String, + pub genesis_time: u64, + pub distribution_schedule: Vec<(u64, u64, Uint128)>, +} +``` + +| Key | Type | Description | +| :--- | :--- | :--- | +| `owner` | HumanAddr | Contract address of mAsset token | +| `mirror_token` | HumanAddr | Final price to freeze revoked mAsset | +| `mint_contract` | HumanAddr | Contract address of Mirror Mint | +| `staking_contract` | HumanAddr | Contract address of Mirror Oracle | +| `commission_collector` | HumanAddr | Contract address of Mirror Collector | +| `oracle_contract` | HumanAddr | Contract address of Mirror Oracle | +| `terraswap_factory` | HumanAddr | Contract address of Terraswap Factory | +| `token_code_id` | u64 | Code ID for CW20 contract for generating new mAssets | +| `base_denom` | String | Native token denom for Terraswaap pairs \(TerraUSD\) | +| `genesis_time` | u64 | Block height which the Factory contract was instantiated | +| `distribution_schedule` | Vec<\(u64, u64, Uint128\)> | Distribution schedule for the minting of new MIR tokens. Each entry consists of: - start time \(seconds\) - end time \(seconds\) distribution amount for the interval Determines the total amount of new MIR tokens minted as rewards for LP stakers over the interval \[start time, end time\]. | {% endtab %} {% tab title="JSON" %} @@ -438,12 +553,45 @@ pub enum QueryMsg { "config": {} } ``` -{% endtab %} -{% endtabs %} + +#### Response + +```javascript +{ + "config_response": { + "owner": "terra1..." + "mirror_token": "terra1...", + "mint_contract": "terra1...", + "staking_contract": "terra1...", + "commission_collector": "terra1...", + "oracle_contract": "terra1...", + "terraswap_factory": "terra1...", + "token_code_id": 8, + "base_denom": "uusd", + "genesis_time": 1000000, + "distribution_schedule": [ + [3600, 7200, "1000000"], + [7200, 10800, "1000000"] + ] + } +} +``` | Key | Type | Description | | :--- | :--- | :--- | - +| `owner` | HumanAddr | Contract address of mAsset token | +| `mirror_token` | HumanAddr | Final price to freeze revoked mAsset | +| `mint_contract` | HumanAddr | Contract address of Mirror Mint | +| `staking_contract` | HumanAddr | Contract address of Mirror Oracle | +| `commission_collector` | HumanAddr | Contract address of Mirror Collector | +| `oracle_contract` | HumanAddr | Contract address of Mirror Oracle | +| `terraswap_factory` | HumanAddr | Contract address of Terraswap Factory | +| `token_code_id` | u64 | Code ID for CW20 contract for generating new mAssets | +| `base_denom` | String | Native token denom for Terraswaap pairs \(TerraUSD\) | +| `genesis_time` | u64 | Block height which the Factory contract was instantiated | +| `distribution_schedule` | Vec<\(u64, u64, Uint128\)> | Distribution schedule for the minting of new MIR tokens. Each entry consists of: start time \(seconds\) end time \(seconds\) distribution amount for the interval Determines the total amount of new MIR tokens minted as rewards for LP stakers over the interval \[start time, end time\]. | +{% endtab %} +{% endtabs %} ### `DistributionInfo` @@ -458,6 +606,25 @@ pub enum QueryMsg { DistributionInfo {} } ``` + +| Key | Type | Description | +| :--- | :--- | :--- | +| `asset_token` | HumanAddr | Contract address of asset token | + +#### Response + +```rust +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] +pub struct DistributionInfoResponse { + pub weights: Vec<(HumanAddr, u32)>, + pub last_distributed: u64, +} +``` + +| Key | Type | Description | +| :--- | :--- | :--- | +| `weights` | Vec<\(HumanAddr, u32\)> | List of reward weight assigned to each mAsset. Each entry consists of: - Token contract address - weight | +| `last_distributed` | u64 | Block height of the most recent reward distribution | {% endtab %} {% tab title="JSON" %} @@ -466,10 +633,29 @@ pub enum QueryMsg { "distribution_info": {} } ``` -{% endtab %} -{% endtabs %} | Key | Type | Description | | :--- | :--- | :--- | | `asset_token` | HumanAddr | Contract address of asset token | +#### Response + +```javascript +{ + "distribution_info_response": { + "weights": [ + ["terra1...", 8], + ["terra1...", 8] + ], + "last_distributed": 3600 + } +} +``` + +| Key | Type | Description | +| :--- | :--- | :--- | +| `weights` | Vec<\(HumanAddr, u32\)> | List of reward weight assigned to each mAsset. Each entry consists of: - Token contract address - weight | +| `last_distributed` | u64 | Block height of the most recent reward distribution | +{% endtab %} +{% endtabs %} + diff --git a/contracts/gov.md b/contracts/gov.md index 1ae60a7..da1d341 100644 --- a/contracts/gov.md +++ b/contracts/gov.md @@ -8,7 +8,7 @@ The Gov Contract keeps a balance of MIR tokens, which it uses to reward stakers ## Config -| Name | Type | Description | +| Key | Type | Description | | :--- | :--- | :--- | | `mirror_token` | HumanAddr | Contract address of Mirror Token \(MIR\) | | `quorum` | Decimal | Minimum percentage of participation required for a poll to pass | @@ -17,6 +17,8 @@ The Gov Contract keeps a balance of MIR tokens, which it uses to reward stakers | `proposal_deposit` | Uint128 | Minimum MIR deposit required for a new poll to be submitted | | `effective_delay` | u64 | Number of blocks after a poll passes to apply changes | | `expiration_period` | u64 | Number of blocks after a poll's voting period during which the poll can be executed. | +| `voter_weight` | Decimal | Ratio of protocol fee which will be distributed among the governance poll voters | +| `snapshot_period` | u64 | Minimum number of blocks before the end of voting period which snapshot could be taken to lock the current quorum for a poll | ## InitMsg @@ -29,8 +31,11 @@ pub struct InitMsg { pub quorum: Decimal, pub threshold: Decimal, pub voting_period: u64, + pub effective_delay: u64, + pub expiration_period: u64, pub proposal_deposit: Uint128, - pub effective_delay: u64 + pub voter_weight: Decimal, + pub snapshot_period: u64, } ``` {% endtab %} @@ -38,13 +43,16 @@ pub struct InitMsg { {% tab title="JSON" %} ```javascript { - "mirror_token": "terra1...", - "quorum": "0.4", - "threshold": "0.5", - "voting_period": 8, - "proposal_deposit": "1000000" - "effective_delay": 8 -} + "mirror_token": "terra1...", + "quorum": "0.1", + "threshold": "0.5", + "voting_period": 8, + "effective_delay": 8, + "expiration_period": 8, + "proposal_deposit": "100000", + "voter_weight": "0.5", + "snapshot_period": 8 +} ``` {% endtab %} {% endtabs %} @@ -57,12 +65,14 @@ pub struct InitMsg { | `voting_period` | u64 | Number of blocks during which votes can be cast | | `proposal_deposit` | Uint128 | Minimum MIR deposit required for a new poll to be submitted | | `effective_delay` | u64 | Number of blocks after a poll passes to apply changes | +| `voter_weight` | Decimal | Ratio of protocol fee which will be distributed among the governance poll voters | +| `snapshot_period` | u64 | Minimum number of blocks before the end of voting period which snapshot could be taken to lock the current quorum for a poll | ## HandleMsg ### `Receive` -Can be called during a CW20 token transfer when the Mint contract is the recipient. Allows the token transfer to execute a [Receive Hook](gov.md#receive-hooks) as a subsequent action within the same transaction. +Can be called during a CW20 token transfer when the Gov contract is the recipient. Allows the token transfer to execute a [Receive Hook](gov.md#receive-hooks) as a subsequent action within the same transaction. {% tabs %} {% tab title="Rust" %} @@ -111,13 +121,15 @@ Updates the configuration for the Gov contract. #[serde(rename_all = "snake_case")] pub enum HandleMsg { UpdateConfig { - effective_delay: Option, owner: Option, - proposal_deposit: Option, quorum: Option, threshold: Option, voting_period: Option, + effective_delay: Option, expiration_period: Option, + proposal_deposit: Option, + voter_weight: Option, + snapshot_period: Option, } } ``` @@ -126,29 +138,34 @@ pub enum HandleMsg { {% tab title="JSON" %} ```javascript { - "update_config": { - "effective_delay": 8, - "owner": "terra1...", - "proposal_deposit": "10000000", - "quorum": "123.456789", - "threshold": "123.456789", - "voting_period": 8, - "expiration_period": 8 - } -} + "update_config": { + "owner": "terra...1", + "mirror_token": "terra1...", + "quorum": "0.1", + "threshold": "0.5", + "voting_period": 8, + "effective_delay": 8, + "expiration_period": 8, + "proposal_deposit": "100000", + "voter_weight": "0.5", + "snapshot_period": 8 + } +} ``` {% endtab %} {% endtabs %} | Key | Type | Description | | :--- | :--- | :--- | -| `effective_delay`\* | u64 | Number of blocks after a poll passes to apply changes | | `owner`\* | HumanAddr | Address of owner of governance contract | -| `proposal_deposit`\* | Uint128 | Minimum deposited MIR tokens for a poll to enter voting | -| `quorum`\* | Decimal | Percentage of participation \(of total staked MIR\) required for a poll to pass | -| `threshold`\* | Decimal | Percentage of `yes` votes needed for a poll to pass | -| `voting_period`\* | u64 | Number of blocks during which votes for a poll can be cast after it has finished its deposit | -| `expiration_period`\* | u64 | Number of blocks after a poll's voting period during which the poll can be executed. | +| `quorum`\* | Decimal | Minimum percentage of participation required for a poll to pass | +| `threshold`\* | Decimal | Minimum percentage of `yes` votes required for a poll to pass | +| `voting_period`\* | u64 | Number of blocks during which votes can be cast | +| `effective_delay`\* | u64 | Number of blocks after a poll passes to apply changes | +| `expiration_period`\* | u64 | Number of blocks after a poll's voting period during which the poll can be executed | +| `proposal_deposit`\* | Uint128 | Minimum MIR deposit required for a new poll to be submitted | +| `voter_weight`\* | Decimal | Ratio of protocol fee which will be distributed among the governance poll voters | +| `snapshot_period`\* | u64 | Minimum number of blocks before end of voting period which snapshot could be taken to lock the current quorum for a poll | \* = optional @@ -163,10 +180,10 @@ Submits a user's vote for an active poll. Once a user has voted, they cannot cha #[serde(rename_all = "snake_case")] pub enum HandleMsg { CastVote { - amount: Uint128, poll_id: u64, vote: VoteOption, - } + amount: Uint128, + }, } ``` {% endtab %} @@ -174,11 +191,11 @@ pub enum HandleMsg { {% tab title="JSON" %} ```javascript { - "cast_vote": { - "amount": "10000000", - "poll_id": 8, - "vote": "yes/no" - } + "cast_vote": { + "amount": "1000000", + "poll_id": 8, + "vote": "yes/no/abstain" + } } ``` {% endtab %} @@ -188,7 +205,7 @@ pub enum HandleMsg { | :--- | :--- | :--- | | `amount` | Uint128 | Amount of voting power \(staked MIR\) to allocate | | `poll_id` | u64 | Poll ID | -| `vote` | VoteOption | Can be `yes` or `no` | +| `vote` | VoteOption | Can be `yes`,`no` or `abstain` | ### `WithdrawVotingTokens` @@ -224,6 +241,54 @@ pub enum HandleMsg { \* = optional +### `WithdrawVotingRewards` + +Withdraws a user’s voting reward for user’s voted governance poll after `end_poll` has happened. + +{% tabs %} +{% tab title="Rust" %} +```rust +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] +#[serde(rename_all = "snake_case")] +pub enum HandleMsg { + WithdrawVotingRewards {}, +} +``` +{% endtab %} + +{% tab title="JSON" %} +```javascript +{ + "withdraw_voting_rewards": {} +} +``` +{% endtab %} +{% endtabs %} + +### `StakeVotingRewards` + +Immediately re-stakes user's voting rewards to Gov Contract. + +{% tabs %} +{% tab title="Rust" %} +```rust +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] +#[serde(rename_all = "snake_case")] +pub enum HandleMsg { + StakeVotingRewards {}, +} +``` +{% endtab %} + +{% tab title="JSON" %} +```javascript +{ + "stake_voting_rewards": {} +} +``` +{% endtab %} +{% endtabs %} + ### `EndPoll` Can be issued by anyone to end the voting for an active poll. Triggers tally the results to determine whether the poll has passed. The current block height must exceed the end height of voting phase. @@ -288,6 +353,38 @@ pub enum HandleMsg { | :--- | :--- | :--- | | `poll_id` | u64 | Poll ID | +### `SnapshotPoll` + +Snapshot of poll’s current `quorum` status is saved when the block height enters `snapshot_period`. + +{% tabs %} +{% tab title="Rust" %} +```rust +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] +#[serde(rename_all = "snake_case")] +pub enum HandleMsg { + SnapshotPoll { + poll_id: u64, + } +} +``` +{% endtab %} + +{% tab title="JSON" %} +```javascript +{ + "snapshot_poll": { + "poll_id": 8 + } +} +``` +{% endtab %} +{% endtabs %} + +| Key | Type | Description | +| :--- | :--- | :--- | +| `poll_id` | u64 | Poll ID | + ## Receive Hooks ### `StakeVotingTokens` @@ -322,7 +419,7 @@ pub enum Cw20HookMsg { ### `CreatePoll` -Issued when sending MIR tokens to the Gov contract to create a new poll. Will only succeed if the amount of tokens sent meets the configured `proposal_deposit` amount. Contains a generic message to be issued by the Gov contract if it passes \(can invoke messages in other contracts it owns\). +Issued when sending MIR tokens to the Gov contract to create a new poll. Will only succeed if the amount of tokens sent meets the configured`proposal_deposit`amount. Contains a generic message to be issued by the Gov contract if it passes \(can invoke messages in other contracts it owns\). {% tabs %} {% tab title="Rust" %} @@ -373,6 +470,30 @@ pub struct ExecuteMsg { \* = optional +### `DepositReward` + +Reward is distributed between MIR stakers and governance poll voters based on `voter_weight` when rewards are sent from [Mirror Collector](collector.md). + +{% tabs %} +{% tab title="Rust" %} +```rust +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] +#[serde(rename_all = "snake_case")] +pub enum Cw20HookMsg { + DepositReward {}, +} +``` +{% endtab %} + +{% tab title="JSON" %} +```javascript +{ + "deposit_reward": {} +} +``` +{% endtab %} +{% endtabs %} + ## QueryMsg ### `Config` @@ -386,6 +507,36 @@ pub enum QueryMsg { Config {} } ``` + +#### Response + +```rust +#[derive(Serialize, Deserialize, Clone, PartialEq, JsonSchema)] +pub struct ConfigResponse { + pub owner: HumanAddr, + pub mirror_token: HumanAddr, + pub quorum: Decimal, + pub threshold: Decimal, + pub voting_period: u64, + pub effective_delay: u64, + pub expiration_period: u64, + pub proposal_deposit: Uint128, + pub voter_weight: Decimal, + pub snapshot_period: u64, +} +``` + +| Key | Type | Description | +| :--- | :--- | :--- | +| `mirror_token` | HumanAddr | Contract address of Mirror Token \(MIR\) | +| `quorum` | Decimal | Minimum percentage of participation required for a poll to pass | +| `threshold` | Decimal | Minimum percentage of `yes` votes required for a poll to pass | +| `voting_period` | u64 | Number of blocks during which votes can be cast | +| `effective_delay` | u64 | Number of blocks after a poll passes to apply changes | +| `expiration_period` | u64 | Number of blocks after a poll's voting period during which the poll can be executed | +| `proposal_deposit` | Uint128 | Minimum MIR deposit required for a new poll to be submitted | +| `voter_weight` | Decimal | Ratio of protocol fee which will be distributed among the governance poll voters | +| `snapshot_period` | u64 | Minimum number of blocks before end of voting period which snapshot could be taken to lock the current quorum for a poll | {% endtab %} {% tab title="JSON" %} @@ -394,12 +545,39 @@ pub enum QueryMsg { "config": {} } ``` -{% endtab %} -{% endtabs %} + +#### Response + +```javascript +{ + "config_response": { + "owner": "terra1...", + "mirror_token": "terra1...", + "quorum": "0.1", + "threshold": "0.5", + "voting_period": 100000, + "effective_delay": 13000, + "expiration_period": 13000, + "proposal_deposit": "1000000", + "voter_weight": "0.5", + "snapshot_period": 1000 + } +} +``` | Key | Type | Description | | :--- | :--- | :--- | - +| `mirror_token` | HumanAddr | Contract address of Mirror Token \(MIR\) | +| `quorum` | Decimal | Minimum percentage of participation required for a poll to pass | +| `threshold` | Decimal | Minimum percentage of `yes` votes required for a poll to pass | +| `voting_period` | u64 | Number of blocks during which votes can be cast | +| `effective_delay` | u64 | Number of blocks after a poll passes to apply changes | +| `expiration_period` | u64 | Number of blocks after a poll's voting period during which the poll can be executed | +| `proposal_deposit` | Uint128 | Minimum MIR deposit required for a new poll to be submitted | +| `voter_weight` | Decimal | Ratio of protocol fee which will be distributed among the governance poll voters | +| `snapshot_period` | u64 | Minimum number of blocks before end of voting period which snapshot could be taken to lock the current quorum for a poll | +{% endtab %} +{% endtabs %} ### `State` @@ -412,6 +590,25 @@ pub enum QueryMsg { State {} } ``` + +#### Response + +```rust +#[derive(Serialize, Deserialize, Clone, PartialEq, JsonSchema)] +pub struct StateResponse { + pub poll_count: u64, + pub total_share: Uint128, + pub total_deposit: Uint128, + pub pending_voting_rewards: Uint128, +} +``` + +| Key | Type | Description | +| :--- | :--- | :--- | +| `poll_count` | u64 | Total number of polls that have been created on Mirror Protocol | +| `total_share` | Uint128 | Amount of staked MIR to governance contract | +| `total_deposit` | Uint128 | Amount of locked MIR to governance polls | +| `pending_voting_rewards` | Uint128 | Amount of voting rewards that are not claimed yet | {% endtab %} {% tab title="JSON" %} @@ -420,12 +617,28 @@ pub enum QueryMsg { "state": {} } ``` -{% endtab %} -{% endtabs %} + +#### Response + +```javascript +{ + "state_response": { + "poll_count": 100, + "total_share": "1000000", + "total_deposit": "1000000", + "pending_voting_rewards": "1000000" + } +} +``` | Key | Type | Description | | :--- | :--- | :--- | - +| `poll_count` | u64 | Total number of polls that have been created on Mirror Protocol | +| `total_share` | Uint128 | Amount of staked MIR to governance contract | +| `total_deposit` | Uint128 | Amount of locked MIR to governance polls | +| `pending_voting_rewards` | Uint128 | Amount of voting rewards that are not claimed yet | +{% endtab %} +{% endtabs %} ### `Staker` @@ -440,6 +653,29 @@ pub enum QueryMsg { } } ``` + +| Key | Type | Description | +| :--- | :--- | :--- | +| `address` | HumanAddr | Address of staker | + +#### Response + +```rust +#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema)] +pub struct StakerResponse { + pub balance: Uint128, + pub share: Uint128, + pub locked_balance: Vec<(u64, VoterInfo)>, + pub pending_voting_rewards: Uint128, +} +``` + +| Key | Type | Description | +| :--- | :--- | :--- | +| `balance` | Uint128 | Amount of MIR staked by the user | +| `share` | Uint128 | Weight of the user's staked MIR | +| `locked_balance` | Vec<\(u64, VoterInfo\)> | Total number of staked MIR used as votes, and chosen vote option | +| `pending_voting_rewards` | u64 | Amount of voting rewards that are not claimed yet | {% endtab %} {% tab title="JSON" %} @@ -450,13 +686,36 @@ pub enum QueryMsg { } } ``` -{% endtab %} -{% endtabs %} | Key | Type | Description | | :--- | :--- | :--- | | `address` | HumanAddr | Address of staker | +#### Response + +```javascript +{ + "staker_response": { + "balance": "1000000", + "share": "1000000", + "locked_balance": [ + [100, yes, "1000000"], + [100, abstain, "1000000"] + ] + "pending_voting_rewards": "1000000" + } +} +``` + +| Key | Type | Description | +| :--- | :--- | :--- | +| `balance` | Uint128 | Amount of MIR staked by the user | +| `share` | Uint128 | Weight of the user's staked MIR | +| `locked_balance` | Vec<\(u64, VoterInfo\)> | Total number of staked MIR used as votes, and chosen vote option | +| `pending_voting_rewards` | u64 | Amount of voting rewards that are not claimed yet | +{% endtab %} +{% endtabs %} + ### `Poll` {% tabs %} @@ -470,6 +729,51 @@ pub enum QueryMsg { } } ``` + +| Key | Type | Description | +| :--- | :--- | :--- | +| `poll_id` | u64 | Poll ID | + +#### Response + +```rust +#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema)] +pub struct PollResponse { + pub id: u64, + pub creator: HumanAddr, + pub status: PollStatus, + pub end_height: u64, + pub title: String, + pub description: String, + pub link: Option, + pub deposit_amount: Uint128, + pub execute_data: Option, + pub yes_votes: Uint128, // balance + pub no_votes: Uint128, // balance + pub abstain_votes: Uint128, // balance + pub total_balance_at_end_poll: Option, + pub voters_reward: Uint128, + pub staked_amount: Option, +} +``` + +| Key | Type | Description | +| :--- | :--- | :--- | +| id | u64 | Poll ID | +| creator | HumanAddr | Address of the poll creator | +| status | PollStatus | Could be one of "in progress", "rejected", "passed", "executed", "expired" | +| end\_height | u64 | Amount of voting rewards that are not claimed yet | +| title | String | Title of the poll | +| description | String | Description submitted by the creator | +| link\* | Uint128 | URL link | +| deposit\_amount | binary | Initial MIR deposit at poll creation | +| execute\_data\* | ExecuteMsg | Message to be executed by Gov contract | +| yes\_votes | Uint128 | Amount of yes votes | +| no\_votes | Uint128 | Amount of no votes | +| abstain\_votes | Uint128 | Amount of abstain votes | +| total\_balance\_at\_end\_poll\* | Uint128 | Total balanced used as yes, no, or abstain votes at the end of the poll | +| voters\_reward | Uint128 | Amount of MIR reward accumulated to be distributed to the voters | +| staked\_amount\* | Uint128 | Total number of MIR staked on governance contract \(used when Snapshot Poll has been taken\) | {% endtab %} {% tab title="JSON" %} @@ -480,13 +784,55 @@ pub enum QueryMsg { } } ``` -{% endtab %} -{% endtabs %} | Key | Type | Description | | :--- | :--- | :--- | | `poll_id` | u64 | Poll ID | +#### Response + +```javascript +{ + "poll_response": { + "id": 8, + "creator": "terra1...", + "status": "in_progress", + "end_height": 1000000, + "title": "Register mCOIN Parameters", + "description": "mCOIN has been...", + "link": "https://mirror.finance", + "deposit_amount": "1000000", + "execute_data": "eyAiZXhlY3V0ZV9tc2ciOiAiYmxhaCBibGFoIiB9", + "yes_votes": "1000000", + "no_votes": "1000000", + "abstain_votes": "1000000", + "total_balance_at_end_poll": "1000000", + "voters_reward": "1000000", + "staked_amount": "1000000" + } +} +``` + +| Key | Type | Description | +| :--- | :--- | :--- | +| id | u64 | Poll ID | +| creator | HumanAddr | Address of the poll creator | +| status | PollStatus | Could be one of "in progress", "rejected", "passed", "executed", "expired" | +| end\_height | u64 | Amount of voting rewards that are not claimed yet | +| title | String | Title of the poll | +| description | String | Description submitted by the creator | +| link\* | Uint128 | URL link | +| deposit\_amount | binary | Initial MIR deposit at poll creation | +| execute\_data\* | ExecuteMsg | Message to be executed by Gov contract | +| yes\_votes | Uint128 | Amount of yes votes | +| no\_votes | Uint128 | Amount of no votes | +| abstain\_votes | Uint128 | Amount of abstain votes | +| total\_balance\_at\_end\_poll\* | Uint128 | Total balanced used as yes, no, or abstain votes at the end of the poll | +| voters\_reward | Uint128 | Amount of MIR reward accumulated to be distributed to the voters | +| staked\_amount\* | Uint128 | Total number of MIR staked on governance contract \(used when Snapshot Poll has been taken\) | +{% endtab %} +{% endtabs %} + ### `Polls` {% tabs %} @@ -502,6 +848,27 @@ pub enum QueryMsg { } } ``` + +| Key | Type | Description | +| :--- | :--- | :--- | +| `filter`\* | PollStatus | Can be `yes` or `no` | +| `limit`\* | u32 | Limit of results to fetch | +| `start_after`\* | u64 | Begins search query at specific ID | + +\* = optional + +#### Response + +```rust +#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema)] +pub struct PollsResponse { + pub polls: Vec, +} +``` + +| Key | Type | Description | +| :--- | :--- | :--- | +| `polls` | Vec<PollResponse> | Array of poll query responses | {% endtab %} {% tab title="JSON" %} @@ -514,8 +881,6 @@ pub enum QueryMsg { } } ``` -{% endtab %} -{% endtabs %} | Key | Type | Description | | :--- | :--- | :--- | @@ -525,6 +890,43 @@ pub enum QueryMsg { \* = optional +#### Response + +```javascript +{ + "polls_response": { + "polls": [ + "poll_response": { + "id": 8, + "creator": "terra1...", + "status": "in_progress", + "end_height": 1000000, + "title": "Register mCOIN Parameters", + "description": "mCOIN has been...", + "link": "https://mirror.finance", + "deposit_amount": "1000000", + "execute_data": "eyAiZXhlY3V0ZV9tc2ciOiAiYmxhaCBibGFoIiB9", + "yes_votes": "1000000", + "no_votes": "1000000", + "abstain_votes": "1000000", + "total_balance_at_end_poll": "1000000", + "voters_reward": "1000000", + "staked_amount": "1000000" + } + ... + ] + } +} +``` + +| Key | Type | Description | +| :--- | :--- | :--- | +| `polls` | Vec<PollResponse> | Array of poll query responses | +{% endtab %} +{% endtabs %} + + + ### `Voters` {% tabs %} @@ -540,6 +942,31 @@ pub enum QueryMsg { } } ``` + +| Key | Type | Description | +| :--- | :--- | :--- | +| `limit`\* | u32 | Limit of results to fetch | +| `poll_id` | u64 | Poll ID | +| `start_after`\* | HumanAddr | Begins search query with prefix | + +\* = optional + +#### Response + +```rust +#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema)] +pub struct VotersResponseItem { + pub voter: HumanAddr, + pub vote: VoteOption, + pub balance: Uint128, +} +``` + +| Key | Type | Description | +| :--- | :--- | :--- | +| `voter` | HumanAddr | Address of the voter | +| `vote` | VoteOption | Could be one of `yes`, `no`, `abstain` | +| `balance` | Uint128 | Amount of staked MIR used for voting | {% endtab %} {% tab title="JSON" %} @@ -552,8 +979,6 @@ pub enum QueryMsg { } } ``` -{% endtab %} -{% endtabs %} | Key | Type | Description | | :--- | :--- | :--- | @@ -563,3 +988,23 @@ pub enum QueryMsg { \* = optional +#### Response + +```rust +{ + "voter_response": { + "voter": "terra1...", + "vote": "yes", + "balance": "1000000" + } +} +``` + +| Key | Type | Description | +| :--- | :--- | :--- | +| `voter` | HumanAddr | Address of the voter | +| `vote` | VoteOption | Could be one of `yes`, `no`, `abstain` | +| `balance` | Uint128 | Amount of staked MIR used for voting | +{% endtab %} +{% endtabs %} + diff --git a/contracts/limit-order.md b/contracts/limit-order.md index 2dff067..e850c3d 100644 --- a/contracts/limit-order.md +++ b/contracts/limit-order.md @@ -1,8 +1,8 @@ # Limit Order -Limit Order allows submission, updates and execution of buy and sell orders at a limit price specified by the users. Once the limit order is submitted and the limit price is reached, market making agents can read the orders from the Limit Order contract and execute them when it provides an arbitrage opportunity. +Limit Order allows submission, updates, and execution of buy and sell orders at a limit price specified by the users. Once the limit order is submitted and the limit price is reached, market-making agents can read the orders from the Limit Order contract and execute them when it provides an arbitrage opportunity. -To create a market making bot for arbitrage opportunity, refer to this [Github link](https://github.com/Mirror-Protocol/mirror-contracts/tree/master/contracts/mirror_limit_order). +To create a market-making bot for arbitrage opportunity, refer to this [Github link](https://github.com/Mirror-Protocol/mirror-contracts/tree/master/contracts/mirror_limit_order). ## InitMsg @@ -277,27 +277,13 @@ pub enum QueryMsg { } } ``` -{% endtab %} - -{% tab title="JSON" %} -```javascript -{ - "order": { - "order_id": 10 - } -} -``` -{% endtab %} -{% endtabs %} | Key | Type | Description | | :--- | :--- | :--- | | `order_id` | u64 | Order ID | -### `OrderResponse` +#### Response -{% tabs %} -{% tab title="Rust" %} ```rust #[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] pub struct OrderResponse { @@ -308,9 +294,32 @@ pub struct OrderResponse { pub filled_offer_amount: Uint128, pub filled_ask_amount: Uint128, ``` + +| Key | Type | Description | +| :--- | :--- | :--- | +| `order_id` | u64 | Order ID | +| `bidder_addr` | HumanAddr | Address of bidder | +| `offer_asset` | Asset | Amount of asset offered in order | +| `ask_asset` | Asset | Amount of asset asked in order | +| `filled_offer_amount` | Uint128 | Amount of offer asset already executed | +| `filled_ask_amount` | Uint128 | Amount of ask asset already executed | {% endtab %} {% tab title="JSON" %} +```javascript +{ + "order": { + "order_id": 10 + } +} +``` + +| Key | Type | Description | +| :--- | :--- | :--- | +| `order_id` | u64 | Order ID | + +#### Response + ```javascript { "OrderResponse": { @@ -337,8 +346,6 @@ pub struct OrderResponse { } } ``` -{% endtab %} -{% endtabs %} | Key | Type | Description | | :--- | :--- | :--- | @@ -348,6 +355,8 @@ pub struct OrderResponse { | `ask_asset` | Asset | Amount of asset asked in order | | `filled_offer_amount` | Uint128 | Amount of offer asset already executed | | `filled_ask_amount` | Uint128 | Amount of ask asset already executed | +{% endtab %} +{% endtabs %} ### `Orders` @@ -366,10 +375,39 @@ pub enum QueryMsg { } } ``` + +| Key | Type | Description | +| :--- | :--- | :--- | +| `bidder_addr`\* | HumanAddr | Address of the order bidder | +| `start_after`\* | u64 | Begins search query at specific Order ID | +| `limit`\* | u32 | Limit of results to fetch | +| `order_by`\* | OrderBy | Can be ASC or DESC | + +#### Response + +```rust +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] +pub struct OrdersResponse { + pub orders: Vec, +} +``` + +| Key | Type | Description | +| :--- | :--- | :--- | +| `orders` | Vec<OrderResponse> | Vector of user's order information | + +| Key | Type | Description | +| :--- | :--- | :--- | +| `order_id` | u64 | Order ID | +| `bidder_addr` | HumanAddr | Address of bidder | +| `offer_asset` | Asset | Amount of asset offered in order | +| `ask_asset` | Asset | Amount of asset asked in order | +| `filled_offer_amount` | Uint128 | Amount of offer asset already executed | +| `filled_ask_amount` | Uint128 | Amount of ask asset already executed | {% endtab %} {% tab title="JSON" %} -``` +```javascript { "orders": { "bidder_addr": "terra1...", @@ -379,8 +417,6 @@ pub enum QueryMsg { } } ``` -{% endtab %} -{% endtabs %} | Key | Type | Description | | :--- | :--- | :--- | @@ -389,22 +425,8 @@ pub enum QueryMsg { | `limit`\* | u32 | Limit of results to fetch | | `order_by`\* | OrderBy | Can be ASC or DESC | -\*=optional - - -### `OrdersResponse` +#### Response -{% tabs %} -{% tab title="Rust" %} -```rust -#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] -pub struct OrdersResponse { - pub orders: Vec, -} -``` -{% endtab %} - -{% tab title="JSON" %} ```javascript { "OrdersResponse": [ @@ -456,12 +478,6 @@ pub struct OrdersResponse { ] } ``` -{% endtab %} -{% endtabs %} - -| Key | Type | Description | -| :--- | :--- | :--- | -| `orders` | Vec<OrderResponse> | Vector of user's order information | | Key | Type | Description | | :--- | :--- | :--- | @@ -471,6 +487,10 @@ pub struct OrdersResponse { | `ask_asset` | Asset | Amount of asset asked in order | | `filled_offer_amount` | Uint128 | Amount of offer asset already executed | | `filled_ask_amount` | Uint128 | Amount of ask asset already executed | +{% endtab %} +{% endtabs %} + +\*=optional ### `LastOrderID` @@ -485,44 +505,40 @@ pub enum QueryMsg { LastOrderID: {} } ``` -{% endtab %} - -{% tab title="JSON" %} -```javascript -{ - "last_order_id": {} -} -``` -{% endtab %} -{% endtabs %} - -| Key | Type | Description | -| :--- | :--- | :--- | -| | | | -### `LastOrderIDResponse` +#### Response -{% tabs %} -{% tab title="Rust" %} ```rust #[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] pub struct LastOrderIDResponse { pub last_order_id:u64 } ``` + +| Key | Type | Description | +| :--- | :--- | :--- | +| `last_order_id` | u64 | Index of the most recent order | {% endtab %} {% tab title="JSON" %} ```javascript { - "LastOrderIDResponse": { + "last_order_id": {} +} +``` + +#### Response + +```javascript +{ + "last_order_id_response": { "last_order_id": 10 } ``` -{% endtab %} -{% endtabs %} | Key | Type | Description | | :--- | :--- | :--- | | `last_order_id` | u64 | Index of the most recent order | +{% endtab %} +{% endtabs %} diff --git a/contracts/lock.md b/contracts/lock.md new file mode 100644 index 0000000..6596355 --- /dev/null +++ b/contracts/lock.md @@ -0,0 +1,305 @@ +# Lock + +The Lock contract is responsible for locking up UST returned from shorting a mAsset through [Mirror Mint](../user-guide/getting-started/mint-and-burn.md) operation. + +## InitMsg + +```rust +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] +pub struct InitMsg { + pub owner: HumanAddr, + pub mint_contract: HumanAddr, + pub base_denom: String, + pub lockup_period: u64, +} +``` + +| Key | Type | Description | +| :--- | :--- | :--- | +| `owner` | HumanAddr | Owner address of Mirror Lock | +| `mint_contract` | HumanAddr | Address of Mirror Mint | +| `base_denom` | String | Native token denomination for stablecoin \(TerraUSD\) | +| `lockup_period` | u64 | Length of time in seconds which the UST from shorting will be locked for | + +## HandleMsg + +### `UpdateConfig` + +Updates the configuration of Lock contract. Can only be issued by the owner of the Mirror Lock. + +{% tabs %} +{% tab title="Rust" %} +```rust +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] +#[serde(rename_all = "snake_case")] +pub enum HandleMsg { + UpdateConfig { + owner: Option, + mint_contract: Option, + base_denom: Option, + lockup_period: Option, + } +``` +{% endtab %} + +{% tab title="JSON" %} +```javascript +{ + "update_config": { + "owner": "terra1...", + "mint_contract": "terra1...", + "base_denom": "uusd", + "lockup_period": 8 + } +} +``` +{% endtab %} +{% endtabs %} + +| Key | Type | Description | +| :--- | :--- | :--- | +| `owner`\* | HumanAddr | Owner address of Mirror Lock | +| `mint_contract`\* | HumanAddr | Address of Mirror Mint | +| `base_denom`\* | String | Native token denomination for stablecoin \(TerraUSD\) | +| `lockup_period`\* | u64 | Length of time in seconds which the UST from shorting witll be locked for | + +\*= optional + +### `LockPositionFundsHook` + +Locks the UST from shorting mAsset when short CDP is successfully created on Mirror Mint. + +{% tabs %} +{% tab title="Rust" %} +```rust +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] +#[serde(rename_all = "snake_case")] +pub enum HandleMsg { + LockPositionFundsHook { + position_idx: Uint128, + receiver: HumanAddr, + } +``` +{% endtab %} + +{% tab title="JSON" %} +```javascript +{ + "lock_position_funds_hook": { + "position_idx": "10", + "receiver": "terra1..." + } +} +``` +{% endtab %} +{% endtabs %} + +| Key | Type | Description | +| :--- | :--- | :--- | +| `position_idx` | Uint128 | ID number of CDP from Mirror Mint | +| `receiver` | HumanAddr | Creator of CDP, who will receive unlocked funds | + +### `UnlockPositionFunds` + +Locked UST from`LockPositionFundsHook`is unlocked by sending this message after`lockup_period`has passed. Can only be issued by the owner of the position \(`receiver`\). + +{% tabs %} +{% tab title="Rust" %} +```rust +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] +#[serde(rename_all = "snake_case")] +pub enum HandleMsg { + UnlockPositionFunds { + position_idx: Uint128, + } +``` +{% endtab %} + +{% tab title="JSON" %} +```javascript +{ + "unlock_position_funds": { + "position_idx": "10" + } +} +``` +{% endtab %} +{% endtabs %} + +| Key | Type | Description | +| :--- | :--- | :--- | +| `position_idx` | Uint128 | ID number of CDP from Mirror Mint to unlock funds from | + +### `ReleasePositionFunds` + +Locked funds will be released and sent to the CDP creator upon closing of the position. This message unlocks funds even when`lock_period`has not ended yet. Can only be issued by the mint contract when the position is being closed. + +{% tabs %} +{% tab title="Rust" %} +```rust +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] +#[serde(rename_all = "snake_case")] +pub enum HandleMsg { + ReleasePositionFunds { + position_idx: Uint128, + } +``` +{% endtab %} + +{% tab title="JSON" %} +```javascript +{ + "release_position_funds": { + "position_idx": "10" + } +} +``` +{% endtab %} +{% endtabs %} + +| Key | Type | Description | +| :--- | :--- | :--- | +| `position_idx` | Uint128 | ID number of CDP from Mirror Mint to unlock funds from | + +## QueryMsg + +### `Config` + +Returns the configuration of Mirror Lock. + +{% tabs %} +{% tab title="Rust" %} +```rust +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] +#[serde(rename_all = "snake_case")] +pub enum QueryMsg { + Config {} +``` + +#### Response + +```rust +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] +pub struct ConfigResponse { + pub owner: HumanAddr, + pub mint_contract: HumanAddr, + pub base_denom: String, + pub lockup_period: u64, +} +``` + +| Key | Type | Description | +| :--- | :--- | :--- | +| `owner` | HumanAddr | Owner address of Mirror Lock | +| `mint_contract` | HumanAddr | Address of Mirror Mint | +| `base_denom` | String | Native token denomination for stablecoin \(TerraUSD\) | +| `lockup_period` | u64 | Length of time in seconds which the UST from shorting will be locked for | +{% endtab %} + +{% tab title="JSON" %} +```javascript +{ + "config": {} +} +``` + + + +#### Response + +```javascript +{ + "config_response": { + "owner": "terra1...", + "mint_contract": "terra1...", + "base_denom": "uusd", + "lockup_period": 10 + } +} +``` + +| Key | Type | Description | +| :--- | :--- | :--- | +| `owner` | HumanAddr | Owner address of Mirror Lock | +| `mint_contract` | HumanAddr | Address of Mirror Mint | +| `base_denom` | String | Native token denomination for stablecoin \(TerraUSD\) | +| `lockup_period` | u64 | Number of blocks which the UST from shorting will be locked for | +{% endtab %} +{% endtabs %} + +### `PositionLockInfo` + +Returns information about locked funds of a specific CDP. + +{% tabs %} +{% tab title="Rust" %} +```rust +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] +#[serde(rename_all = "snake_case")] +pub enum QueryMsg { + PositionLockInfo { + position_idx: Uint128, + } +``` + +| Key | Type | Description | +| :--- | :--- | :--- | +| `position_idx` | Uint128 | ID number of CDP from Mirror Mint to unlock funds from | + +#### Response + +```rust +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] +pub struct PositionLockInfoResponse { + pub idx: Uint128, + pub receiver: HumanAddr, + pub locked_amount: Uint128, + pub unlock_time: u64, +} +``` + +| Key | Type | Description | +| :--- | :--- | :--- | +| `idx` | Uint128 | ID number of CDP from Mirror Mint to unlock funds from | +| `receiver` | HumanAddr | Creator of CDP, who will receive unlocked funds | +| `locked_amount` | Uint128 | Amount of `base_denom` locked from creating a Short CDP | +| `unlock_time` | u64 | Time when user is allowed to claim the `locked_amount` | +{% endtab %} + +{% tab title="JSON" %} +```javascript +{ + "position_lock_info": { + "position_idx": "10" + } +} +``` + +| Key | Type | Description | +| :--- | :--- | :--- | +| `position_idx` | Uint128 | ID number of CDP from Mirror Mint to unlock funds from | + +#### Response + +```rust +{ + "position_lock_info_response": { + "idx": "10", + "receiver": "terra1...", + "locked_funds": [ + [100, "1400"] + ] + } +} +``` + +| Key | Type | Description | +| :--- | :--- | :--- | +| `idx` | Uint128 | ID number of CDP from Mirror Mint to unlock funds from | +| `receiver` | HumanAddr | Creator of CDP, who will receive unlocked funds | +| `locked_funds` | Vec<\(u64, Uint128\)> | Description about 1. Block height which the fund was locked at 2. Amount of `base_denom` locked from creating a Short CDP | +{% endtab %} +{% endtabs %} + + + diff --git a/contracts/mint.md b/contracts/mint.md index efa8026..59bbb67 100644 --- a/contracts/mint.md +++ b/contracts/mint.md @@ -1,6 +1,10 @@ # Mint -The Mint Contract implements the logic for [Collateralized Debt Positions ](../protocol/mirrored-assets-massets.md#collateralized-debt-position)\(CDPs\), through which users can mint new mAsset tokens against their deposited collateral \(UST or mAssets\). Current prices of collateral and minted mAssets are read from the [Oracle Contract](oracle.md) determine the C-ratio of each CDP. The Mint Contract also contains the logic for liquidating CDPs with C-ratios below the minimum for their minted mAsset through auction. +The Mint Contract implements the logic for [Collateralized Debt Positions ](../protocol/mirrored-assets-massets.md#collateralized-debt-position)\(CDPs\), through which users can mint or short new mAsset tokens against their deposited collateral \(UST or mAssets\). + +Current prices of collateral and minted mAssets are read from the [Collateral Oracle](collateral-oracle.md) and [Oracle Contract](oracle.md) to determine the C-ratio of each CDP. Depending on which the type of asset used as the collateral, the minimum collateral ratio of each CDP may change. Collateral Oracle is responsible for feeding prices and collateral ratio `multiplier` of each collateral asset type. + +The Mint Contract also contains the logic for liquidating CDPs with C-ratios below the minimum for their minted mAsset through auction. ## InitMsg @@ -12,6 +16,10 @@ pub struct InitMsg { pub owner: HumanAddr, pub oracle: HumanAddr, pub collector: HumanAddr, + pub collateral_oracle: HumanAddr, + pub staking: HumanAddr, + pub terraswap_factory: HumanAddr, + pub lock: HumanAddr, pub base_denom: String, pub token_code_id: u64, pub protocol_fee_rate: Decimal, @@ -25,8 +33,13 @@ pub struct InitMsg { "owner": "terra1...", "oracle": "terra1...", "collector": "terra1...", + "collateral_oracle": "terra1...", + "staking": "terra1...", + "terraswap_factory": "terra1...", + "lock": "terra1...", + "base_denom": "uusd", "token_code_id": 8, - "protocol_fee_rate": "0.123", + "protocol_fee_rate": "0.123 } ``` {% endtab %} @@ -37,6 +50,10 @@ pub struct InitMsg { | `owner` | HumanAddr | Owner of contract | | `oracle` | HumanAddr | Contract address of [Mirror Oracle](oracle.md) | | `collector` | HumanAddr | Contract address of [Mirror Collector](collector.md) | +| `collateral_oracle` | HumanAddr | Contract address of [Mirror Collateral Oracle](collateral-oracle.md) | +| `staking` | HumanAddr | Contract address of [Mirror Staking](staking.md) | +| `terraswap_factory` | HumanAddr | Contract address of Terraswap Factory | +| `lock` | HumanAddr | Contract address of [Mirror Lock](lock.md) | | `base_denom` | String | Native token denomination for stablecoin \(TerraUSD\) | | `token_code_id` | u64 | Code ID for Terraswap CW20 Token | | `protocol_fee_rate` | Decimal | Protocol fee | @@ -97,6 +114,9 @@ pub enum HandleMsg { owner: Option, oracle: Option, collector: Option, + collateral_oracle: Option, + terraswap_factory: Option, + lock: Option, token_code_id: Option, protocol_fee_rate: Option, } @@ -111,6 +131,10 @@ pub enum HandleMsg { "owner": "terra1...", "oracle": "terra1...", "collector": "terra1...", + "collateral_oracle": "terra1...", + "staking": "terra1...", + "terraswap_factory": "terra1...", + "lock": "terra1...", "token_code_id": 8, "protocol_fee_rate": "0.123", } @@ -124,6 +148,8 @@ pub enum HandleMsg { | `owner`\* | HumanAddr | New owner | | `oracle`\* | u64 | New oracle contract address | | `collector`\* | HumanAddr | New collector contract address | +| `terraswap_factory`\* | HumanAddr | Contract address of Terraswap Factory | +| `lock`\* | HumanAddr | Contract address of Mirror Lock | | `token_code_id`\* | u64 | New token code ID | | `protocol_fee_rate`\* | Decimal | New protocol fee rate | @@ -143,8 +169,16 @@ pub enum HandleMsg { asset_info: AssetInfo, auction_discount: Option, min_collateral_ratio: Option, + ipo_params: Option } } + +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] +pub struct IPOParams { + pub mint_end: u64, + pub pre_ipo_price: Decimal, + pub min_collateral_ratio_after_ipo: Decimal, +} ``` {% endtab %} @@ -158,7 +192,12 @@ pub enum HandleMsg { } }, "auction_discount": "123.456789", - "min_collateral_ratio": "123.456789" + "min_collateral_ratio": "123.456789", + "ipo_params": { + "mint_end": "10000000", + "pre_ipo_price": "7.77", + "min_collateral_ratio_after_ipo": "1.5" + } } } ``` @@ -170,9 +209,18 @@ pub enum HandleMsg { | `asset_info` | AssetInfo | Asset to be updated | | `auction_discount`\* | Decimal | New auction discount rate | | `min_collateral_ratio`\* | Decimal | New minimum collateralization ratio | +| `ipo_params`\* | IPOParams | Parameters to be used for Pre-IPO asset | \* = optional +#### IPOParams + +| Key | Type | Description | +| :--- | :--- | :--- | +| `mint_end` | u64 | Time which `mint_period` ends | +| `pre_ipo_price` | Decimal | Fixed price to be used to mint during `mint_period` | +| `min_collateral_ratio_after_ipo` | Decimal | Minimum collateralization ratio to be used after IPO is triggered \(Used for pre-IPO\) | + ### `RegisterAsset` Registers a new mAsset to be mintable. @@ -182,24 +230,28 @@ Registers a new mAsset to be mintable. ```rust #[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] #[serde(rename_all = "snake_case")] -pub enum HandleMsg { +pub enum HandleMsg { RegisterAsset { asset_token: HumanAddr, auction_discount: Decimal, min_collateral_ratio: Decimal, - } -} + ipo_params: Option + }, ``` {% endtab %} {% tab title="JSON" %} ```javascript { - "register_asset": { - "asset_token": "terra1...", - "auction_discount": "123.456789", - "min_collateral_ratio": "123.456789" - } + "register_asset": { + "asset_token": "terra1...", + "auction_discount": "0.2", + "min_collateral_ratio": "1.5", + "ipo_params": { + "mint_end": "10000000", + "pre_ipo_price": "7.77", + "min_collateral_ratio_after_ipo": "1.5" + } } ``` {% endtab %} @@ -207,9 +259,46 @@ pub enum HandleMsg { | Key | Type | Description | | :--- | :--- | :--- | -| `asset_token` | HumanAddr | Asset to be registered | +| `asset_token` | HumanAddr | Contract address of mAsset to be registered | | `auction_discount` | Decimal | Auction discount rate | | `min_collateral_ratio` | Decimal | Minimum collateralization ratio | +| `ipo_params`\* | IPOParams | Parameters to be used for Pre-IPO asset | + +\*= optional + +### `TriggerIPO` + +Asset feeder is allowed to trigger IPO event on pre-IPO asset to have the following characters: + +* Oracle feeder now feeds real-time price of the underlying asset +* The asset becomes mintable again, even after the `mint_period` has ended + +{% tabs %} +{% tab title="Rust" %} +```rust +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] +#[serde(rename_all = "snake_case")] +pub enum HandleMsg { + TriggerIPO { + asset_token: HumanAddr, + }, +``` +{% endtab %} + +{% tab title="JSON" %} +```javascript +{ + "trigger_ipo": { + "asset_token": "terra1..." + } +} +``` +{% endtab %} +{% endtabs %} + +| Key | Type | Description | +| :--- | :--- | :--- | +| `asset_token` | HumanAddr | Contract address of the token | ### `RegisterMigration` @@ -264,11 +353,12 @@ let mint_amount = collateral.amount ```rust #[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] #[serde(rename_all = "snake_case")] -pub enum HandleMsg { +pub enum HandleMsg { OpenPosition { - asset_info: AssetInfo, collateral: Asset, + asset_info: AssetInfo, collateral_ratio: Decimal, + short_params: Option, } } @@ -288,22 +378,26 @@ pub enum AssetInfo { {% tab title="JSON" %} ```javascript { - "open_position": { - "asset_info": { - "token": { - "contract_addr": "terra1..." - } - }, - "collateral": { - "info": { - "token": { - "contract_address": "terra1..." + "open_position": { + "collateral": { + "info": { + "token": { + "contract_addr": "terra1..." + } + }, + "amount": "1000000" + }, + "asset_info": { + "token": { + "contract_addr": "terra1..." + } + }, + "collateral_ratio": "1.5", + "short_params": { + "belief_price": "123.456789", + "max_spread": "0.1" } - }, - "amount": "1000000" - }, - "collateral_ratio": "123.456789" - } + } } ``` {% endtab %} @@ -314,6 +408,32 @@ pub enum AssetInfo { | `asset_info` | AssetInfo | Asset to be minted by CDP | | `collateral` | Asset | Initial collateral deposit for the CDP | | `collateral_ratio` | Decimal | Initial desired collateralization ratio | +| `short_params`\* | ShortParams | Terraswap Price and spread limit to immediately short tokens after CDP creation \(used for "Short"\) | + +\*= optional + +#### `ShortParams` + +If optional `short_params` is added, mint contract will immediately sell the minted mAssets and`sLP` tokens will be minted and sent to the user. The UST obtained from the operation will be added to the user's lock position in [lock contract](lock.md). + +{% tabs %} +{% tab title="Rust" %} +```rust +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] +pub struct ShortParams { + pub belief_price: Option, + pub max_spread: Option, +} +``` +{% endtab %} +{% endtabs %} + +| Key | Type | Description | +| :--- | :--- | :--- | +| `belief_price`\* | Decimal | Price submitted to the Terraswap pool | +| `max_spread`\* | Decimal | Maximum slippage accepted during swap transaction against the Terraswap Pool | + +\*=optional ### `Deposit` @@ -416,6 +536,7 @@ pub enum HandleMsg { Mint { asset: Asset, position_idx: Uint128, + short_params: Option, } } ``` @@ -425,6 +546,7 @@ pub enum HandleMsg { ```javascript { "mint": { + "position_idx": "10000000", "asset": { "info": { "token": { @@ -433,7 +555,10 @@ pub enum HandleMsg { }, "amount": "1000000" }, - "position_idx": "10000000" + "short_params": { + "belief_price": "123.456789", + "max_spread": "0.1" + } } } ``` @@ -442,8 +567,9 @@ pub enum HandleMsg { | Key | Type | Description | | :--- | :--- | :--- | -| `asset` | Asset | mAssets to be minted | | `position_idx` | Uint128 | Index of position | +| `asset` | Asset | mAssets to be minted | +| `short_params` | ShortParams | Terraswap Price and maximum slippage tolerance to be applied for selling minted token after position creation \(used for "Short"\) | ## Receive Hooks @@ -466,6 +592,7 @@ pub enum Cw20HookMsg { OpenPosition { asset_info: AssetInfo, collateral_ratio: Decimal, + short_params: Option, } } ``` @@ -480,7 +607,11 @@ pub enum Cw20HookMsg { "contract_addr": "terra1..." } }, - "collateral_ratio": "123.456789" + "collateral_ratio": "123.456789", + "short_params": { + "belief_price": "123.456789", + "max_spread": "0.1" + } } } ``` @@ -491,6 +622,7 @@ pub enum Cw20HookMsg { | :--- | :--- | :--- | | `asset_info` | AssetInfo | mAsset to be minted by CDP | | `collateral_ratio` | Decimal | Initial collateralization ratio to use | +| `short_params` | ShortParams | Terraswap Price and spread limit to immediately short tokens after CDP creation \(used for "Short"\) | ### `Deposit` @@ -532,7 +664,7 @@ pub enum Cw20HookMsg { ### `Burn` -Issued when a user sends mAsset tokens to the Mint contract. +Issued when a user sends mAsset tokens to the Mint contract. Burns the sent tokens against a CDP and reduces the C-ratio. If all outstanding minted mAsset tokens are burned, the position is closed and the collateral is returned. @@ -617,6 +749,37 @@ pub enum QueryMsg { Config {} } ``` + +#### Response + +```rust +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] +pub struct ConfigResponse { + pub owner: HumanAddr, + pub oracle: HumanAddr, + pub collector: HumanAddr, + pub collateral_oracle: HumanAddr, + pub staking: HumanAddr, + pub terraswap_factory: HumanAddr, + pub lock: HumanAddr, + pub base_denom: String, + pub token_code_id: u64, + pub protocol_fee_rate: Decimal, +} +``` + +| Key | Type | Description | +| :--- | :--- | :--- | +| `owner` | HumanAddr | Owner of contract | +| `oracle` | HumanAddr | Contract address of [Mirror Oracle](oracle.md) | +| `collector` | HumanAddr | Contract address of [Mirror Collector](collector.md) | +| `collateral_oracle` | HumanAddr | Contract address of Mirror Collateral Oracle | +| `staking` | HumanAddr | Contract address of Mirror Staking | +| `terraswap_factory` | HumanAddr | Contract address of Terraswap Factory | +| `lock` | HumanAddr | Contract address of Mirror Lock | +| `base_denom` | String | Native token denomination for stablecoin \(TerraUSD\) | +| `token_code_id` | u64 | Code ID for Terraswap CW20 Token | +| `protocol_fee_rate` | Decimal | Protocol fee | {% endtab %} {% tab title="JSON" %} @@ -625,12 +788,40 @@ pub enum QueryMsg { "config": {} } ``` -{% endtab %} -{% endtabs %} + +#### Response + +```rust +{ + "config_response": { + "owner": "terra1...", + "oracle": "terra1...", + "collector": "terra1...", + "collateral_oracle": "terra1...", + "staking": "terra1...", + "terraswap_factory": "terra1...", + "lock": "terra1...", + "base_denom": "uusd", + "token_code_id": 8, + "protocol_fee_rate": "123.456789" + } +} +``` | Key | Type | Description | | :--- | :--- | :--- | - +| `owner` | HumanAddr | Owner of contract | +| `oracle` | HumanAddr | Contract address of [Mirror Oracle](oracle.md) | +| `collector` | HumanAddr | Contract address of [Mirror Collector](collector.md) | +| `collateral_oracle` | HumanAddr | Contract address of Mirror Collateral Oracle | +| `staking` | HumanAddr | Contract address of Mirror Staking | +| `terraswap_factory` | HumanAddr | Contract address of Terraswap Factory | +| `lock` | HumanAddr | Contract address of Mirror Lock | +| `base_denom` | String | Native token denomination for stablecoin \(TerraUSD\) | +| `token_code_id` | u64 | Code ID for Terraswap CW20 Token | +| `protocol_fee_rate` | Decimal | Protocol fee | +{% endtab %} +{% endtabs %} ### `AssetConfig` @@ -645,6 +836,33 @@ pub enum QueryMsg { } } ``` + +| Key | Type | Description | +| :--- | :--- | :--- | +| `asset_token` | HumanAddr | Contract address of asset to query | + +#### Response + +```rust +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] +pub struct AssetConfigResponse { + pub token: HumanAddr, + pub auction_discount: Decimal, + pub min_collateral_ratio: Decimal, + pub end_price: Option, + pub ipo_params: Option, +} +``` + +| Key | Type | Description | +| :--- | :--- | :--- | +| `token` | HumanAddr | Contract address of asset to query | +| `auction_discount` | Decimal | Discount rate applied for liquidation auction | +| `min_collateral_ratio` | Decimal | Lowest collateral ratio to mint this mAsset | +| `end_price`\* | Decimal | Fixed oracle price of mAsset when migration / Pre-IPO / Delisting occurs | +| `ipo_params`\* | u64 | Parameters to be used for Pre-IPO assets | + +\*= optional {% endtab %} {% tab title="JSON" %} @@ -659,13 +877,41 @@ pub enum QueryMsg { } } ``` -{% endtab %} -{% endtabs %} | Key | Type | Description | | :--- | :--- | :--- | | `asset_token` | HumanAddr | Contract address of asset to query | +#### Response + +```rust +{ + "asset_config_response": { + "token": "terra1...", + "auction_discount": "0.2", + "min_collateral_ratio": "1.5", + "end_price": "123.456789", + "ipo_params": { + "mint_end": "10000000", + "pre_ipo_price": "7.77", + "min_collateral_ratio_after_ipo": "1.5" + } + } +} +``` + +| Key | Type | Description | +| :--- | :--- | :--- | +| `token` | HumanAddr | Contract address of asset to query | +| `auction_discount` | Decimal | Discount rate applied for liquidation auction | +| `min_collateral_ratio` | Decimal | Lowest collateral ratio to mint this mAsset | +| `end_price`\* | Decimal | Fixed oracle price of mAsset when migration / Pre-IPO / Delisting occurs | +| `ipo_params`\* | u64 | Parameters to be used for Pre-IPO assets | + +\*= optional +{% endtab %} +{% endtabs %} + ### `Position` {% tabs %} @@ -679,6 +925,31 @@ pub enum QueryMsg { } } ``` + +| Key | Type | Description | +| :--- | :--- | :--- | +| `position_idx` | Uint128 | Index of position to query | + +#### Response + +```rust +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] +pub struct PositionResponse { + pub idx: Uint128, + pub owner: HumanAddr, + pub collateral: Asset, + pub asset: Asset, + pub is_short: bool, +} +``` + +| Name | Type | Description | +| :--- | :--- | :--- | +| `idx` | Uint128 | Index of CDP | +| `owner` | HumanAddr | Address of CDP owner | +| `collateral` | Asset | Asset used as collateral | +| `asset` | Asset | Asset minted by CDP | +| `is_short` | bool | Determines if CDP is short position or not | {% endtab %} {% tab title="JSON" %} @@ -689,12 +960,99 @@ pub enum QueryMsg { } } ``` + +| Key | Type | Description | +| :--- | :--- | :--- | +| `position_idx` | Uint128 | Index of position to query | + +#### Response + +```rust +{ + "position_response": { + "idx": "100", + "owner": "terra1...", + "collateral": { + "info": { + "token": { + "contract_addr": "terra1..." + } + }, + "amount": "1000000" + }, + "asset": { + "info": { + "token": { + "contract_addr": "terra1..." + } + }, + "amount": "1000000" + }, + "is_short": true + } +} +``` + +| Name | Type | Description | +| :--- | :--- | :--- | +| `idx` | Uint128 | Index of CDP | +| `owner` | HumanAddr | Address of CDP owner | +| `collateral` | Asset | Asset used as collateral | +| `asset` | Asset | Asset minted by CDP | +| `is_short` | bool | Determines if CDP is short position or not | {% endtab %} {% endtabs %} +### `NextPositionIdx` + +Returns the most recent position ID +1. + +{% tabs %} +{% tab title="Rust" %} +```rust +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] +#[serde(rename_all = "snake_case")] +pub enum QueryMsg { + NextPositionIdx {} +} +``` + +#### Response + +```rust +#[derive(Serialize, Deserialize, Clone, PartialEq, JsonSchema, Debug, Default)] +pub struct NextPositionIdxResponse { + pub next_position_idx: Uint128, +} +``` + | Key | Type | Description | | :--- | :--- | :--- | -| `position_idx` | Uint128 | Index of position to query | +| `next_position_idx` | Uint128 | Index of the next position to be created | +{% endtab %} + +{% tab title="JSON" %} +```javascript +{ + "next_position_idx": {} +} +``` + +#### Response + +```rust +{ + "next_position_idex_response": { + "next_position_idx": "1000000" + } +} +``` + +| Key | Type | Description | +| :--- | :--- | :--- | +| `next_position_idx` | Uint128 | Index of the next position to be created | +{% endtab %} +{% endtabs %} ### `Positions` diff --git a/contracts/oracle.md b/contracts/oracle.md index 313c25b..4e2313e 100644 --- a/contracts/oracle.md +++ b/contracts/oracle.md @@ -57,7 +57,7 @@ pub enum HandleMsg { ### `RegisterAsset` -Registers a new asset with the oracle, enabling a price feed for the asset. The feeder account responsible for reporting the price is assigned at this step. +Registers a new asset with the oracle, enabling a price feed for the asset. The feeder account responsible for reporting the price is assigned at this step. Can also be used to update an existing asset. {% tabs %} {% tab title="Rust" %} @@ -140,6 +140,21 @@ pub enum QueryMsg { Config {} } ``` + +#### Response + +```rust +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] +pub struct ConfigResponse { + pub owner: HumanAddr, + pub base_asset: String, +} +``` + +| Key | Type | Description | +| :--- | :--- | :--- | +| `owner` | HumanAddr | Owner address | +| `base_asset` | String/`'uusd'` | Asset in which prices will be denominated \(default TerraUSD\) | {% endtab %} {% tab title="JSON" %} @@ -148,12 +163,24 @@ pub enum QueryMsg { "config": {} } ``` -{% endtab %} -{% endtabs %} + +#### Response + +```rust +{ + "config_response": { + "owner": "terra1...", + "base_asset": "uusd" + } +} +``` | Key | Type | Description | | :--- | :--- | :--- | - +| `owner` | HumanAddr | Owner address | +| `base_asset` | String/`'uusd'` | Asset in which prices will be denominated \(default TerraUSD\) | +{% endtab %} +{% endtabs %} ### `Feeder` @@ -170,6 +197,25 @@ pub enum QueryMsg { } } ``` + +| Key | Type | Description | +| :--- | :--- | :--- | +| `asset_token` | HumanAddr | Contract address of asset token to query | + +#### Response + +```rust +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] +pub struct FeederResponse { + pub asset_token: HumanAddr, + pub feeder: HumanAddr, +} +``` + +| Key | Type | Description | +| :--- | :--- | :--- | +| `asset_token` | HumanAddr | Contract address of asset token to query | +| `feeder` | HumanAddr | Terra address of price feeder | {% endtab %} {% tab title="JSON" %} @@ -180,13 +226,29 @@ pub enum QueryMsg { } } ``` -{% endtab %} -{% endtabs %} | Key | Type | Description | | :--- | :--- | :--- | | `asset_token` | HumanAddr | Contract address of asset token to query | +#### Response + +```rust +{ + "feeder_response": { + "asset_token": "terra1...", + "feeder": "terra1..." + } +} +``` + +| Key | Type | Description | +| :--- | :--- | :--- | +| `asset_token` | HumanAddr | Contract address of asset token to query | +| `feeder` | HumanAddr | Terra address of price feeder | +{% endtab %} +{% endtabs %} + ### `Price` Get price information for the specified mAsset. @@ -203,6 +265,28 @@ pub enum QueryMsg { } } ``` + +| Key | Type | Description | +| :--- | :--- | :--- | +| `base_asset` | HumanAddr | Asset for which to get price | +| `quote_asset` | HumanAddr / `'uusd'` | Asset in which price will be denominated | + +#### Response + +```rust +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] +pub struct PriceResponse { + pub rate: Decimal, + pub last_updated_base: u64, + pub last_updated_quote: u64, +} +``` + +| Key | Type | Description | +| :--- | :--- | :--- | +| `rate` | HumanAddr | Asset for which to get price | +| `last_updated_base` | u64 | Block height which the `base_asset` price has been updated at | +| `last_updated_quote` | u64 | Block height which the `quote_asset` price has been updated at | {% endtab %} {% tab title="JSON" %} @@ -214,14 +298,32 @@ pub enum QueryMsg { } } ``` -{% endtab %} -{% endtabs %} | Key | Type | Description | | :--- | :--- | :--- | | `base_asset` | HumanAddr | Asset for which to get price | | `quote_asset` | HumanAddr / `'uusd'` | Asset in which price will be denominated | +#### Response + +```rust +{ + "price_response": { + "rate": "123.456789", + "last_updated_base": 10 + "last_updated_quote": 10 + } +} +``` + +| Key | Type | Description | +| :--- | :--- | :--- | +| `rate` | HumanAddr | Asset for which to get price | +| `last_updated_base` | u64 | Block height which the `base_asset` price has been updated at | +| `last_updated_quote` | u64 | Block height which the `quote_asset` price has been updated at | +{% endtab %} +{% endtabs %} + ### `Prices` Get price information for all registered mAssets. @@ -238,6 +340,28 @@ pub enum QueryMsg { } } ``` + +| Key | Type | Description | +| :--- | :--- | :--- | +| `start_after`\* | HumanAddr | Contract address to start query from | +| `limit` | u32 | Max number of results to report | + +#### Response + +```rust +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] +pub struct PricesResponseElem { + pub asset_token: HumanAddr, + pub price: Decimal, + pub last_updated_time: u64, +} +``` + +| Key | Type | Description | +| :--- | :--- | :--- | +| `asset_token` | HumanAddr | Contract address to start query from | +| `price` | Decimal | Current price of the `asset_token` | +| `last_updated_time` | u64 | Block height which the`asset_token`price has been updated at | {% endtab %} {% tab title="JSON" %} @@ -249,11 +373,30 @@ pub enum QueryMsg { } } ``` -{% endtab %} -{% endtabs %} | Key | Type | Description | | :--- | :--- | :--- | | `start_after`\* | HumanAddr | Contract address to start query from | | `limit` | u32 | Max number of results to report | +#### Response + +```rust +{ + "prices_response": { + "asset_token": "terra1...", + "price": "123.456789", + "last_updated_time": 10, + } + ... +} +``` + +| Key | Type | Description | +| :--- | :--- | :--- | +| `asset_token` | HumanAddr | Contract address to start query from | +| `price` | Decimal | Current price of the `asset_token` | +| `last_updated_time` | u64 | Block height which the`asset_token`price has been updated at | +{% endtab %} +{% endtabs %} + diff --git a/contracts/staking.md b/contracts/staking.md index 8987425..5a324fd 100644 --- a/contracts/staking.md +++ b/contracts/staking.md @@ -2,27 +2,48 @@ The Staking Contract contains the logic for LP Token staking and reward distribution. Staking rewards for LP stakers come from the new MIR tokens generated at each block by the [Factory Contract](factory.md) and are split between all combined staking pools. The new MIR tokens are distributed in proportion to size of staked LP tokens multiplied by the weight of that asset's staking pool. -## Config - -| Name | Type | Description | -| :--- | :--- | :--- | -| `owner` | HumanAddr | Address of owner of staking contract | -| `mirror_token` | HumanAddr | Contract address of the Mirror Token \(MIR\) | - ## InitMsg +{% tabs %} +{% tab title="Rust" %} ```rust #[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] pub struct InitMsg { pub owner: HumanAddr, pub mirror_token: HumanAddr, + pub mint_contract: HumanAddr, + pub oracle_contract: HumanAddr, + pub terraswap_factory: HumanAddr, + pub base_denom: String, + pub premium_min_update_interval: u64, } ``` +{% endtab %} + +{% tab title="JSON" %} +```javascript +{ + "owner": "terra1...", + "mirror_token": "terra1...", + "mint_contract": "terra1...", + "oracle_contract": "terra1...", + "terraswap_factory": "terra1...", + "base_denom": "uusd", + "premium_min_update_interval": 8 +} +``` +{% endtab %} +{% endtabs %} | Key | Type | Description | | :--- | :--- | :--- | -| `owner` | HumanAddr | Address of staking contract owner | +| `owner` | HumanAddr | Owner address of Staking contract | | `mirror_token` | HumanAddr | Contract address of the Mirror Token \(MIR\) | +| `mint_contract` | HumanAddr | Contract address of Mirror Mint | +| `oracle_contract` | HumanAddr | Contract address of Mirror Oracle | +| `terraswap_factory` | HumanAddr | Contract address of Terraswap Factory | +| `base_denom` | String | Native token denom for Terraswap pairs \(TerraUSD\) | +| `premium_min_update_interval` | u64 | Interval of time denominated in number of blocks which the collateral premium information is updated | ## HandleMsg @@ -75,28 +96,31 @@ Updates the Staking contract's configuration. Can only be issued by the staking ```rust #[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] #[serde(rename_all = "snake_case")] -pub struct enum HandleMsg { +pub enum HandleMsg { UpdateConfig { owner: Option, + premium_min_update_interval: Option, } -} + ``` {% endtab %} {% tab title="JSON" %} ```javascript { - "update_config": { - "owner": "terra1..." - } + "update_config": { + "owner": "terra1...", + "premium_min_update_interval": 8 + } } ``` {% endtab %} {% endtabs %} -| Key | Type | Description | +| Name | Type | Description | | :--- | :--- | :--- | -| `owner`\* | HumanAddr | Address of new owner of staking contract | +| `owner`\* | HumanAddr | Owner address of Staking contract | +| `premium_min_update_interval`\* | u64 | Interval of time denominated in number of blocks which the collateral premium information is updated | \* = optional @@ -204,6 +228,214 @@ pub enum HandleMsg { \* = optional +### `AutoStake` + +When providing liquidity in Mirror Protocol, asset pair is first sent to Staking contract, and it acts as a relay. When defined assets are sent to the contract, the contract provides liquidity to receive LP tokens and starts `AutoStakeHook`. + +{% hint style="warning" %} +Note: Executor of the transaction should first increase allowance to spend CW20 tokens +{% endhint %} + +{% tabs %} +{% tab title="Rust" %} +```rust +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] +#[serde(rename_all = "snake_case")] +pub enum HandleMsg { + AutoStake { + assets: [Asset; 2], + slippage_tolerance: Option, + } +} +``` +{% endtab %} + +{% tab title="JSON" %} +```javascript +{ +"auto_stake": { + "assets": [ + "info": { + "native_token": { + "denom": "uusd", + } + }, + "amount": "1000000", + "info": { + "token": { + "contract_address": "terra1..." + } + }, + "amount": "1000000", + ], + "slippage_tolerance": "1.234567" + } +} +``` +{% endtab %} +{% endtabs %} + +| Key | Type | Description | +| :--- | :--- | :--- | +| `assets`\* | Array\[Assets\] | Information of assets that are provided into liquidity pool | +| `slippage_tolerance`\* | Decimal | Maximum price slippage allowed to execute this transaction | + +\*= optional + +### `AutoStakeHook` + +`[INTERNAL]` + +Hook to stake the minted LP tokens from providing liquidity. + +{% tabs %} +{% tab title="Rust" %} +```rust +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] +#[serde(rename_all = "snake_case")] +pub enum HandleMsg { + AutoStakeHook { + asset_token: HumanAddr, + staking_token: HumanAddr, + staker_addr: HumanAddr, + prev_staking_token_amount: Uint128, + } +} +``` +{% endtab %} + +{% tab title="JSON" %} +```javascript +{ + "auto_stake_hook": { + "asset_token": "terra1...", + "staking_token": "terra1...", + "staker_addr": "terra1...", + "prev_staking_token_amount: "1000000" + }, +} +``` +{% endtab %} +{% endtabs %} + +| Key | Type | Description | +| :--- | :--- | :--- | +| `assets_token` | HumanAddr | Contract address of the asset token | +| `staking_token` | HumanAddr | Contract address of the LP token to be staked | +| `staker_addr` | HumanAddr | Address of the staker | +| `prev_staking_token_amount` | Uint128 | LP staking balance of the staker before this transaction | + +### `AdjustPremium` + +`[Permission-less operation]` +Changes the price premium rate for a specified mAsset, can be done by anyone. Message can be sent again after a defined `premium_min_update_interval`. + +{% tabs %} +{% tab title="Rust" %} +```rust +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] +#[serde(rename_all = "snake_case")] +pub enum HandleMsg { + AdjustPremium { + asset_tokens: Vec, + } +``` +{% endtab %} + +{% tab title="JSON" %} +```javascript +{ + "adjust_premium": { + "asset_tokens": [ + "terra1...", "terra1..." + ] + } +} +``` +{% endtab %} +{% endtabs %} + +| Key | Type | Description | +| :--- | :--- | :--- | +| `asset_tokens` | Vec<HumanAddr> | Array of token contract addresses to update new price premium rate | + +### **`IncreaseShortToken`** + +`[Mint contract operation]` +Increases the total staked supply of `sLP` tokens for a specific staker. + +{% tabs %} +{% tab title="Rust" %} +```rust +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] +#[serde(rename_all = "snake_case")] +pub enum HandleMsg { + IncreaseShortToken { + asset_token: HumanAddr, + staker_addr: HumanAddr, + amount: Uint128, + } +} +``` +{% endtab %} + +{% tab title="JSON" %} +```javascript +{ + "increase_short_token": { + "asset_token": "terra1...", + "staker_addr": "terra1...", + "amount": "1000000" + } +} +``` +{% endtab %} +{% endtabs %} + +| Key | Type | Description | +| :--- | :--- | :--- | +| `asset_token` | HumanAddr | Token contract address of `sLP` | +| `staker_addr` | HumanAddr | Address of the `sLP` staker | +| `amount` | Uint128 | Amount of `sLP` supply to be increased | + +### `DecreaseShortToken` + +`[Mint contract operations]` +Decreases the total staked supply of `sLP` tokens for a specific staker. + +{% tabs %} +{% tab title="Rust" %} +```rust +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] +#[serde(rename_all = "snake_case")] +pub enum HandleMsg { + DecreaseShortToken { + asset_token: HumanAddr, + staker_addr: HumanAddr, + amount: Uint128, + } +``` +{% endtab %} + +{% tab title="JSON" %} +```javascript +{ + "decrease_short_token": { + "asset_token": "terra1...", + "staker_addr": "terra1...", + "amount": "1000000" + } +} +``` +{% endtab %} +{% endtabs %} + +| Key | Type | Description | +| :--- | :--- | :--- | +| `asset_token` | HumanAddr | Token contract address of `sLP` | +| `staker_addr` | HumanAddr | Address of the `sLP` staker | +| `amount` | Uint128 | Amount of `sLP` supply to be decreased | + ## Receive Hooks ### `Bond` @@ -291,6 +523,31 @@ pub enum QueryMsg { Config {} } ``` + +#### Response + +```rust +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] +pub struct ConfigResponse { + pub owner: HumanAddr, + pub mirror_token: HumanAddr, + pub mint_contract: HumanAddr, + pub oracle_contract: HumanAddr, + pub terraswap_factory: HumanAddr, + pub base_denom: String, + pub premium_min_update_interval: u64, +} +``` + +| Key | Type | Description | +| :--- | :--- | :--- | +| `owner` | HumanAddr | Owner address of Staking contract | +| `mirror_token` | HumanAddr | Contract address of the Mirror Token \(MIR\) | +| `mint_contract` | HumanAddr | Contract address of Mirror Mint | +| `oracle_contract` | HumanAddr | Contract address of Mirror Oracle | +| `terraswap_factory` | HumanAddr | Contract address of Terraswap Factory | +| `base_denom` | String | Native token denom for Terraswap pairs \(TerraUSD\) | +| `premium_min_update_interval` | u64 | Interval of time denominated in number of blocks which the collateral premium information is updated | {% endtab %} {% tab title="JSON" %} @@ -299,12 +556,34 @@ pub enum QueryMsg { "config": {} } ``` -{% endtab %} -{% endtabs %} -| Key | Type | Description | -| :--- | :--- | :--- | +#### Response +```javascript +{ + "config_response": { + "owner": "terra1...", + "mirror_token": "terra1...", + "mint_contract": "terra1...", + "oracle_contract": "terra1...", + "terraswap_factory": "terra1...", + "base_denom": "uusd", + "premium_min_update_interval": 8 + } +} +``` + +| Name | Type | Description | +| :--- | :--- | :--- | +| `owner` | HumanAddr | Owner address of Staking contract | +| `mirror_token` | HumanAddr | Contract address of the Mirror Token \(MIR\) | +| `mint_contract` | HumanAddr | Contract address of Mirror Mint | +| `oracle_contract` | HumanAddr | Contract address of Mirror Oracle | +| `terraswap_factory` | HumanAddr | Contract address of Terraswap Factory | +| `base_denom` | String | Native token denom for Terraswap pairs \(TerraUSD\) | +| `premium_min_update_interval` | u64 | Interval of time denominated in number of blocks which the collateral premium information is updated | +{% endtab %} +{% endtabs %} ### `PoolInfo` @@ -319,6 +598,43 @@ pub enum QueryMsg { } } ``` + +| Key | Type | Description | +| :--- | :--- | :--- | +| `asset_token` | HumanAddr | Asset token to query \(staking pool identifier\) | + +#### Response + +```rust +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] +pub struct PoolInfoResponse { + pub asset_token: HumanAddr, + pub staking_token: HumanAddr, + pub total_bond_amount: Uint128, + pub total_short_amount: Uint128, + pub reward_index: Decimal, + pub short_reward_index: Decimal, + pub pending_reward: Uint128, + pub short_pending_reward: Uint128, + pub premium_rate: Decimal, + pub short_reward_weight: Decimal, + pub premium_updated_time: u64, +} +``` + +| Key | Type | Description | +| :--- | :--- | :--- | +| `asset_token` | HumanAddr | Contract address of mAsset token | +| `staking_token` | HumanAddr | Contract address of `LP` or `sLP` token | +| `total_bond_amount` | Uint128 | Amount of total LP staked | +| `total_short_amount` | Uint128 | Amount of total sLP staked | +| `reward_index` | Decimal | Amount of reward distributed per 1 LP token | +| `short_reward_index` | Decimal | Amount of reward distributed per 1 sLP token | +| `pending_reward` | Uint128 | Amount of unclaimed rewards by LP stakers | +| `short_pending_reward` | Uint128 | Amount of unclaimed rewards by sLP stakers | +| `premium_rate` | Decimal | Current price premium of the asset pool | +| `short_reward_weight` | Decimal | Current reward weight for sLP staking | +| `premium_updated_time` | u64 | Block height which the price premium data for this asset is most recently updated | {% endtab %} {% tab title="JSON" %} @@ -326,15 +642,48 @@ pub enum QueryMsg { { "pool_info": { "asset_token": "terra1..." - } +Key +``` + +| Type | Description | | +| :--- | :--- | :--- | +| `asset_token` | HumanAddr | Asset token to query \(staking pool identifier\) | + +#### Response + +```javascript +{ + "pool_info_response": { + "asset_token": "terra1...", + "staking_token": "terra1...", + "total_bond_amount": "1000000", + "total_short_amount": "1000000", + "reward_index": "123.456789", + "short_reward_index": "123.456789", + "pending_reward": "123.456789", + "short_pending_reward": "123.456789", + "premium_rate": "0.4", + "short_reward_weight": "0.4", + "premium_updated_time": 8 + } } ``` -{% endtab %} -{% endtabs %} | Key | Type | Description | | :--- | :--- | :--- | -| `asset_token` | HumanAddr | Asset token to query \(staking pool identifier\) | +| `asset_token` | HumanAddr | Contract address of mAsset token | +| `staking_token` | HumanAddr | Contract address of `LP` or `sLP` token | +| `total_bond_amount` | Uint128 | Amount of total LP staked | +| `total_short_amount` | Uint128 | Amount of total sLP staked | +| `reward_index` | Decimal | Amount of reward distributed per 1 LP token | +| `short_reward_index` | Decimal | Amount of reward distributed per 1 sLP token | +| `pending_reward` | Uint128 | Amount of unclaimed rewards by LP stakers | +| `short_pending_reward` | Uint128 | Amount of unclaimed rewards by sLP stakers | +| `premium_rate` | Decimal | Current price premium of the asset pool | +| `short_reward_weight` | Decimal | Current reward weight for sLP staking | +| `premium_updated_time` | u64 | Block height which the price premium data for this asset is most recently updated | +{% endtab %} +{% endtabs %} ### `RewardInfo` @@ -350,6 +699,32 @@ pub enum QueryMsg { } } ``` + +| Key | Type | Description | +| :--- | :--- | :--- | +| `asset_token`\* | HumanAddr | Asset token to query. If empty, returns info for all staking pools. | +| `staker` | HumanAddr | Address of staker to query | + +\*= optional + +#### Response + +```rust +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] +pub struct RewardInfoResponseItem { + pub asset_token: HumanAddr, + pub bond_amount: Uint128, + pub pending_reward: Uint128, + pub is_short: bool, +} +``` + +| Key | Type | Description | +| :--- | :--- | :--- | +| `asset_token` | HumanAddr | Asset token being queried | +| `bond_amount` | Uint128 | Amount of LP or sLP tokens staked | +| `pending_reward` | Uint128 | Amount of reward that are not claimed | +| `is_short` | bool | Identifies of the pool os LP or sLP pool | {% endtab %} {% tab title="JSON" %} @@ -361,13 +736,33 @@ pub enum QueryMsg { } } ``` -{% endtab %} -{% endtabs %} | Key | Type | Description | | :--- | :--- | :--- | | `asset_token`\* | HumanAddr | Asset token to query. If empty, returns info for all staking pools. | | `staker` | HumanAddr | Address of staker to query | -\* = optional +\*= optional + +#### Response + +```javascript +{ + "reward_info_response_item": { + "asset_token": "terra1...", + "bond_amount": "1000000", + "pending_reward": "1000000", + "is_short": true + } +} +``` + +| Key | Type | Description | +| :--- | :--- | :--- | +| `asset_token` | HumanAddr | Asset token being queried | +| `bond_amount` | Uint128 | Amount of LP or sLP tokens staked | +| `pending_reward` | Uint128 | Amount of reward that are not claimed | +| `is_short` | bool | Identifies of the pool os LP or sLP pool | +{% endtab %} +{% endtabs %} diff --git a/faq.md b/faq.md index 4cab215..350c5dd 100644 --- a/faq.md +++ b/faq.md @@ -58,7 +58,7 @@ Without the trust that mAssets should be pegged to oracle prices, mAsset prices #### 9. What are the benefits of providing liquidity? -Providing liquidity for the Mirror Protocol is equivalent to locking up your liquidity in Terraswap. By doing so, you ensure that there is a sufficient supply of assets to be traded at any point in time. As compensation for providing liquidity, you will receive LP tokens which accrue trading commission charged by the protocol. In addition, staking these LP tokens provides inflationary rewards in the form of MIR tokens. To learn more about the specifics, see [here](protocol/lp-token.md#lp-commission-rewards). +Providing liquidity for the Mirror Protocol is equivalent to locking up your liquidity in Terraswap. By doing so, you ensure that there is a sufficient supply of assets to be traded at any point in time. As compensation for providing liquidity, you will receive LP tokens which accrue trading commission charged by the protocol. In addition, staking these LP tokens provides inflationary rewards in the form of MIR tokens. To learn more about the specifics, see [here](). #### 10. Is there any risk to providing liquidity to the Terraswap pools? diff --git a/networks.md b/networks.md index 3821c7f..06e0e71 100644 --- a/networks.md +++ b/networks.md @@ -10,7 +10,7 @@ A web application called [Terra Bridge](user-guide/terra-bridge.md) provides web Mirror's core contracts are implemented on the [Terra blockchain](https://terra.money). -### Mainnet +### Mainnet \(v1\) Network chain ID: `columbus-4` @@ -49,7 +49,7 @@ Network chain ID: `columbus-4` | mFB | [terra1mqsjugsugfprn3cvgxsrr8akkvdxv2pzc74us7](https://finder.terra.money/columbus-4/account/terra1mqsjugsugfprn3cvgxsrr8akkvdxv2pzc74us7) | | mCOIN | [terra18wayjpyq28gd970qzgjfmsjj7dmgdk039duhph](https://finder.terra.money/columbus-4/address/terra18wayjpyq28gd970qzgjfmsjj7dmgdk039duhph) | -### Testnet +### Testnet \(v2\) Network chain ID: `tequila-0004` @@ -57,7 +57,7 @@ Network chain ID: `tequila-0004` | Contract | Address | | :--- | :--- | -| Collector | [terra1v046ktavwzlyct5gh8ls767fh7hc4gxc95grxy](https://finder.terra.money/tequila-0004/account/terra12r5ghc6ppewcdcs3hkewrz24ey6xl7mmpk478s) | +| Collector | [terra1v046ktavwzlyct5gh8ls767fh7hc4gxc95grxy](https://finder.terra.money/tequila-0004/account/terra1v046ktavwzlyct5gh8ls767fh7hc4gxc95grxy) | | Community | [terra10qm80sfht0zhh3gaeej7sd4f92tswc44fn000q](https://finder.terra.money/tequila-0004/account/terra10qm80sfht0zhh3gaeej7sd4f92tswc44fn000q) | | Factory | [terra10l9xc9eyrpxd5tqjgy6uxrw7dd9cv897cw8wdr](https://finder.terra.money/tequila-0004/account/terra10l9xc9eyrpxd5tqjgy6uxrw7dd9cv897cw8wdr) | | Gov | [terra12r5ghc6ppewcdcs3hkewrz24ey6xl7mmpk478s](https://finder.terra.money/tequila-0004/account/terra12r5ghc6ppewcdcs3hkewrz24ey6xl7mmpk478s) | @@ -65,7 +65,9 @@ Network chain ID: `tequila-0004` | Oracle | [terra1uvxhec74deupp47enh7z5pk55f3cvcz8nj4ww9](https://finder.terra.money/tequila-0004/account/terra1uvxhec74deupp47enh7z5pk55f3cvcz8nj4ww9) | | Staking | [terra1a06dgl27rhujjphsn4drl242ufws267qxypptx](https://finder.terra.money/tequila-0004/account/terra1a06dgl27rhujjphsn4drl242ufws267qxypptx) | | Airdrop | [terra1p6nvyw7vz3fgpy4nyh3q3vc09e65sr97ejxn2p](https://finder.terra.money/tequila-0004/account/terra1p6nvyw7vz3fgpy4nyh3q3vc09e65sr97ejxn2p) | -| Limit Order | [terra1vc4ch0z3n6c23f9uywzy5yqaj2gmpnam8qgge7](https://finder.terra.money/tequila-0004/address/terra1vc4ch0z3n6c23f9uywzy5yqaj2gmpnam8qgge7) | +| Limit Order | [terra1vc4ch0z3n6c23f9uywzy5yqaj2gmpnam8qgge7](https://finder.terra.money/tequila-0004/account/terra1vc4ch0z3n6c23f9uywzy5yqaj2gmpnam8qgge7) | +| Collateral Oracle | [terra1q3ls6u2glsazdeu7dxggk8d04elnvmsg0ung6n](https://finder.terra.money/tequila-0004/account/terra1q3ls6u2glsazdeu7dxggk8d04elnvmsg0ung6n) | +| Lock | [terra1pcxghd4dyf950mcs0kmlp7lvnrjsnl6qlfldwj](https://finder.terra.money/tequila-0004/account/terra1pcxghd4dyf950mcs0kmlp7lvnrjsnl6qlfldwj) | #### Asset Contracts diff --git a/protocol/governance/README.md b/protocol/governance/README.md index 97336cf..e86cd8c 100644 --- a/protocol/governance/README.md +++ b/protocol/governance/README.md @@ -30,11 +30,11 @@ Staked MIR tokens utilized in on-going polls cannot be withdrawn until the poll ## Procedure -The following steps outlines the governance procedure: +The following steps outline the governance procedure: 1. A new poll is created with an initial deposit that meets `proposal_deposit` -2. The poll enters the voting phase, where it can voted for by anybody with a staked MIR position. Users can vote `yes` or `no`, and can assign how many of their staked MIR to use for voting. +2. The poll enters the voting phase, where it can voted for by anybody with a staked MIR position. Users can vote `yes`, `no` or `abstain` and can assign how many of their staked MIR to use for voting. 3. The voting period ends after `voting_period` blocks have passed. 4. The poll's votes are tallied and **passes** if both quorum \(minimum participation of all staked MIR\) and threshold \(minimum ratio of `yes` to `no` votes\) are met. -5. If the poll passes, its contents will be executed after `effective_delay` blocks have ended. The poll must be executed prior to `expiration_period,` otherwise it will automatically expire and no longer be considered valid. +5. If the poll passes, its contents will be executed after `effective_delay` blocks have ended. The poll must be executed prior to `expiration_period`, otherwise it will automatically expire and no longer be considered valid. diff --git a/protocol/governance/delist-procedure.md b/protocol/governance/delist-procedure.md new file mode 100644 index 0000000..88216e5 --- /dev/null +++ b/protocol/governance/delist-procedure.md @@ -0,0 +1,8 @@ +# Delist Procedure + +As whitelisting of a new mAsset is fully governed in a decentralized way by MIR stakers, they can also choose to [**delist**](../mirrored-assets-massets.md#delisting-and-migration) a specific mAsset that is already registered on Mirror Protocol by submitting a new poll which should define which mAsset should be delisted. + +When the submitted poll is approved by governance, the corresponding mAsset will be labeled as delisted and users will be able to unstake LP & sLP, withdraw collateral, close CDP and burn their delisted asset holdings against any CDP to claim the respective value of the collateral from any position. + +To read more about asset delisting process, refer to this [document](../mirrored-assets-massets.md#delisting-and-migration). + diff --git a/protocol/governance/modify-mint-parameters.md b/protocol/governance/modify-mint-parameters.md index addc9b6..09716aa 100644 --- a/protocol/governance/modify-mint-parameters.md +++ b/protocol/governance/modify-mint-parameters.md @@ -2,7 +2,7 @@ The mechanics of a mint position on the Mirror Protocol is determined by two parameters, `Auction Discount` and `Minimum Collateral Ratio`. At the genesis of the Mirror Protocol, these two parameters have been uniformly set to 20% and 150% respectively for all listed mAssets. -However, the structure of financial markets of the underlying assets are not static, so it is not unreasonable to expect that the Mirror Protocol should also be able to adapt to these changes. To further account for the fact that mirrored assets come in a variety of classes, the two mint parameters can be voted separately for each individual asset. +However, the structure of financial markets of the underlying assets are not static, so it is not unreasonable to expect that the Mirror Protocol should also be able to adapt to these changes. To further account for the fact that mirrored assets come in a variety of classes, the two mint parameters can be voted separately for each individual asset. The community is able to change the two parameters of an existing mAsset through a [**Modify Mint Parameters**](proposal-types.md#4-modify-mint-parameters) ****poll. diff --git a/protocol/governance/pre-ipo-procedure.md b/protocol/governance/pre-ipo-procedure.md new file mode 100644 index 0000000..38fc3b8 --- /dev/null +++ b/protocol/governance/pre-ipo-procedure.md @@ -0,0 +1,13 @@ +# Pre-IPO Procedure + +{% hint style="info" %} +Pre-IPO asset whitelisting discussion can be started at the [Mirror Protocol Forum](https://forum.mirror.finance). +{% endhint %} + +To enable minting of Pre-IPO asset, two separate governance polls must be passed. Pre-IPO asset whitelisting process consists of the steps below: + +1. The user should create **Suggest Pre-IPO Asset** poll. The poll should provide required details and supporting information for the voters to be able to make an informed decision. An example would be to utilize the external link to provide further information about the proposal in the [Mirror Protocol Forum](https://forum.mirror.finance/). Information included could potentially include an [official registration statement](https://www.sec.gov/Archives/edgar/data/1679788/000162828021003168/coinbaseglobalincs-1.htm) of the IPO asset. +2. Once the poll above is completed and passed, a subsequent **Register Pre-IPO Parameters** should be created with oracle feeder address, pre-IPO asset parameters and post-IPO asset parameters which will be effective immediately after the IPO event. +3. If the second poll passes, Pre-IPO asset will be listed after `effective_delay`, and the asset will enter `mint_period`. During `mint_period`, Pre-IPO asset will be mintable at the submitted price, using `mint_collateral_ratio`, tradable and providable to liquidity pools. +4. When the underlying asset is publicly listed, [Mirror Oracle](../../contracts/oracle.md) will start updating the price of mAsset to mimic the real-world asset's price. This mAsset will now be treated like any other mAsset, allowing trading, minting and liquidity provision. + diff --git a/protocol/governance/proposal-types.md b/protocol/governance/proposal-types.md index d34acf9..caa9590 100644 --- a/protocol/governance/proposal-types.md +++ b/protocol/governance/proposal-types.md @@ -1,20 +1,12 @@ # Proposal Types -Governance proposals on the Mirror Protocol can come in a variety of formats. There are six different categories of proposals that can be made: **Whitelist a New mAsset**, **Register Whitelist Parameters**, **Modify Mint Parameters**, **Modify Governance Parameters**, **Spend Community Pool**, and **Submit Text Proposal**. +Governance proposals on the Mirror Protocol can come in a variety of formats. There are four main categories of governance proposals: **Asset Listing, Reward Distribution, Parameter Modification, and Suggestion / Others.** -![Governance Poll Types](../../.gitbook/assets/2020-12-21-2.00.31.png) +![](../../.gitbook/assets/image%20%28190%29.png) -### 1. Submit text poll +### Asset Listing -The function of the text proposal is to allow proposals that do not fit the defined categories. Given that it is a basic text proposal, simple fields for the `Title`, `Description`, and an `Information Link` for additional information. - -| Field | Description | Type | -| :--- | :--- | :--- | -| Title | Title of the poll | Required | -| Description | Short description of the poll | Required | -| Information Link | External URL for further information | Optional | - -### 2. Whitelist a New mAsset +#### 1. Suggest Asset Whitelisting {% hint style="info" %} The full process of getting a new asset to be fully operational on the Mirror Protocol is described [here](whitelist-procedure.md). @@ -22,13 +14,13 @@ The full process of getting a new asset to be fully operational on the Mirror Pr The function of this proposal is to start a poll to whitelist a new asset. Given that this is a simple text proposal, there are a few fields that need to be filled. The `Asset Name`, `Ticker`, `Listed Exchange`, and `Reason for listing` are required. Due to the limitations on the length of the description field of the underlying smart contracts, the current maximum length is 64 bytes \(will be increased to 1024 bytes on December 31, 2020\). It is suggested that additional information be added on a separate web page and linked to using the `Information Link` field. -![Example Whitelist Poll](../../.gitbook/assets/2020-12-21-6.57.30.png) +![](../../.gitbook/assets/image%20%28138%29.png) -Information that would be necessary for a voter to make an informed decisions should be clearly stated in addition to reasons for listing this asset and the asset name and ticker. For example, simply stating: +Information that would be necessary for a voter to make informed decisions should be clearly stated in addition to reasons for listing this asset and the asset name and ticker. For example, simply stating: `Google should be listed because it is a popular stock` -has numerous problems. First, the specific exchange that the price feed should be taken from is not clearly stated \(many companies are dual listed\). Second, Google actually has two stocks that are publicly traded: `GOOGL` and `GOOG` \(the former has voting rights whereas the latter does not\). In addition, the official name registered with NASDAQ is not `Google` but rather `Alphabet Inc.` Thus it is extremely important to make it as clear as possible to others about the asset that you intend to whitelist. +has numerous problems. First, the specific exchange that the price feed should be taken from is not clearly stated \(many companies are dual-listed\). Second, Google actually has two stocks that are publicly traded: `GOOGL` and `GOOG` \(the former has voting rights whereas the latter does not\). In addition, the official name registered with NASDAQ is not `Google` but rather `Alphabet Inc.` Thus it is extremely important to make it as clear as possible to others about the asset that you intend to whitelist. | Field | Description | Type | | :--- | :--- | :--- | @@ -39,13 +31,13 @@ has numerous problems. First, the specific exchange that the price feed should b | Information Link | External URL for further information | Optional | | Suggested Oracle | Oracle provider or address | Optional | -### 3. Register Whitelist Parameters +#### 2. Register Whitelist Parameters If a proposal to whitelist is approved, another poll must be passed to set the parameters of the newly listed asset. The required fields include `Title`, `Description`, `Asset Name`, `Symbol`, `Oracle Feeder` \(address\), `Auction Discount`, and the `Minimum Collateral Ratio`. Again, it is advised to include reference to the passed whitelist poll as well as reasoning for choosing the given oracle address. Given that the Mirror Protocol is in its early stages, it is advisable to keep the parameters equal to existing parameters for already listed assets \(Auction Discount at 20%, and Minimum Collateral Ratio at 150%\). -The original 13 mAssets utilize Band Protocol’s feeders, so a rough guideline to communicate with Band Protocol to receive the oracle address is provided below. If another another oracle address would like to be suggested, please input the address in the Oracle Feeder field. +The original 13 mAssets utilize Band Protocol’s feeders, so a rough guideline to communicate with Band Protocol to receive the oracle address is provided below. If another oracle address would like to be suggested, please input the address in the Oracle Feeder field. -![Example Register Whitelist Parameter Poll](../../.gitbook/assets/2020-12-21-2.53.31.png) +![](../../.gitbook/assets/image%20%28177%29.png) {% hint style="info" %} To ensure proper functioning of the price feed, newly whitelisted asset on Mirror Protocol also undergo a 1 week testing period where the prices are still fed by the oracle but no buy/sell, mint, or staking actions can be performed. @@ -63,11 +55,84 @@ To ensure proper functioning of the price feed, newly whitelisted asset on Mirro | Auction Discount | Discount ratio applied during CDP liquidation auction | Required | | Minimum Collateral Ratio | Minimum collateral ratio applied when opening a mint position | Required | -### 4. Modify Mint Parameters +#### 3. Suggest Pre-IPO Asset + +![](../../.gitbook/assets/image%20%28181%29.png) + +The function of this proposal is to start a poll to whitelist an asset which is scheduled to go through an initial public offering \(or IPO\), but is not publicly listed yet. Similar to the "Suggest asset whitelisting" proposal, this is also a text proposal. Fields that need to be filled are `Asset Name`, `Ticker`, `Listed Exchange`, and `Reason for listing`. It is suggested that additional information on the IPO or supporting information to be added using the `Information Link` field. + +| Field | Description | Type | +| :--- | :--- | :--- | +| Title | Name of the asset to be whitelisted | Required | +| Reason for listing | Short description of whitelist reason | Required | +| Asset Name | Name of the asset to be whitelisted | Required | +| Symbol | Ticker of the asset to be whitelisted | Required | +| Listed Exchange | Exchange which the underlying asset will be traded on | Required | +| Information Link | External URL for further information | Optional | +| Suggested Oracle | Oracle provider or address | Optional | + +#### 4. Register Pre-IPO Parameters + +![](../../.gitbook/assets/image%20%28155%29.png) + +After the proposal to [suggest Pre-IPO asset](proposal-types.md#2-suggest-pre-ipo-asset) is approved, an additional poll to register the asset to Mirror Protocol must be submitted and executed. + +| Field | Description | Type | +| :--- | :--- | :--- | +| Title | Title of the poll | Required | +| Description | Short description of whitelist reason | Required | +| Information Link | External URL for further information | Optional | +| Asset Name | Name of the asset to be whitelisted | Required | +| Symbol | Ticker of the asset to be whitelisted | Required | +| Reference Poll ID | Poll ID of the referenced poll | Optional | +| Listed Exchange | Exchange which the underlying asset will be traded on | Required | +| Oracle Feeder | Oracle Feeder address | Required | +| Auction Discount \(after IPO\) | Discount ratio applied during CDP liquidation auction for Post-IPO asset | Required | +| Min collateral ratio \(after IPO\) | Minimum collateral ratio to be used for mint operations for Post-IPO asset | Required | +| Min Collateral Ratio \(during mint period\) | Collateral ratio to be applied during `mint_period` | Required | +| Mint Period | Number of seconds which mint operation will be allowed for Pre-IPO asset | Required | +| Pre-IPO Price | Fixed price decided by official IPO registration statement, which will be used for Pre-IPO asset | Required | + +#### 5. Delist Asset + +![](../../.gitbook/assets/image%20%28173%29.png) + +Specific mAsset on Mirror Protocol is delisted upon approval and execution of this poll. More information about delisting can be found [here](../mirrored-assets-massets.md#delisting-and-migration). + +| Field | Description | Type | +| :--- | :--- | :--- | +| Title | Name of the asset to be whitelisted | Required | +| Description | Short description of whitelist reason | Required | +| Information Link | External URL for further information | Optional | +| Asset Name | Droplist of mAsset on Mirror Protocol | Required | + +### Reward Distribution + +This category allows modification of two types of MIR distribution: 1\) mAsset LP staking reward; 2\) Governance voting reward. + +#### 1. Modify mAsset Reward Distribution + +![](../../.gitbook/assets/image%20%28203%29.png) + +Through this poll, the ratio which newly minted MIR tokens are distributed among LP token stakers, called `weight` parameter can be changed. To learn how `weight` parameter determines the amount of MIR distributed to each mAsset pool refer to [this document](). + +| Field | Description | Type | +| :--- | :--- | :--- | +| Title | Name of the asset to be whitelisted | Required | +| Reasons for modifying weight parameter | Short description of whitelist reason | Required | +| Information Link | External URL for further information | Optional | +| Asset | Droplist of mAsset on Mirror Protocol, which to change weight parameter for | Required | +| Weight | Weight parameter to be applied for LP staking reward distribution | Required | + +### Parameter Modification + +This poll category allows modification of mAsset, governance contract, collateral and premium tolerance parameters in Mirror Protocol. + +#### 1. Modify mint parameters Through this poll, the existing Mirror Protocol parameters for a specific individual mAsset can be modified. The possible parameters to be updated consist of either the `Auction Discount` and the `Minimum Collateral Ratio`. -![Example Modify Mint Parameters Poll](../../.gitbook/assets/2020-12-21-3.02.00.png) +![](../../.gitbook/assets/image%20%28150%29.png) | Field | Description | Type | | :--- | :--- | :--- | @@ -78,11 +143,11 @@ Through this poll, the existing Mirror Protocol parameters for a specific indivi | Auction Discount | Discount ratio applied during CDP liquidation auction | Required | | Minimum Collateral Ratio | Minimum collateral ratio applied when opening a mint position | Required | -### 5. Modify Governance Parameters +#### 2. Modify governance parameters -Similar to modifying mint parameters, governance parameters such as the `Quorum`, `Threshold`, `Voting Period`, `Effective Delay`, `Expiration Period`, and `Proposal Deposit` can be modified. +Similar to modifying mint parameters, governance parameters such as the `Quorum`, `Threshold`, `Voting Period`, `Effective Delay`, `Expiration Period`, `Proposal Deposit` and `Voter Weight` can be modified. -![Example Modify Governance Parameters poll](../../.gitbook/assets/2020-12-21-3.07.10.png) +![](../../.gitbook/assets/image%20%28193%29.png) | Fields | Description | Type | | :--- | :--- | :--- | @@ -91,16 +156,34 @@ Similar to modifying mint parameters, governance parameters such as the `Quorum` | Information Link | External URL for further information | Optional | | Quorum | Minimum quorum required for accepting a poll \(in percentage\) | Optional | | Threshold | Minimum percentage of `YES` votes to pass a poll \(in percentage\) | Optional | -| Voting Period | Length of poll \(in units of blocks\) | Optional | -| Effective Delay | Length of delay before protocol integration for a passed poll \(in units of blocks\) | Optional | -| Expiration Period | Length of expiration period when for a failed poll \(in units of blocks\) | Optional | +| Voting Period | Length of poll \(in units of seconds\) | Optional | +| Effective Delay | Length of delay before protocol integration for a passed poll \(in units of seconds\) | Optional | +| Expiration Period | Length of expiration period when for a failed poll \(in units of seconds\) | Optional | | Proposal Deposit | Minimum deposit to start a poll \(in units of MIR\) | Optional | +| Voter Weight | Ratio of rewards to be distributed to governance voting participants | Optional | + +#### 3. Modify collateral parameters -### 6. Spend community pool +![](../../.gitbook/assets/image%20%28192%29.png) + +Through this poll, existing collateral's `multiplier` or `oracle address` can be modified. + +| Field | Description | Type | +| :--- | :--- | :--- | +| Title | Title of the poll | Required | +| Reasons for modifying collateral parameter | Short description of the poll | Required | +| Information Link | External URL for further information | Optional | +| Collateral \(Asset\) | Droplist of collateral types on Mirror Protocol, which to modify parameter for | Required | +| Multiplier | Number to be `min_collateral_ratio` of the asset being minted | Required | +| Collateral Oracle Feeder | Address of the collateral oracle used for this asset type | Required | + +### Suggestions / Others + +#### 1. Spend Community Pool Proposals relating to spending the accrued MIR tokens in the community pool can be made under this section. The proposal should ideally specify the reasons for the distribution and identify the recipient and amount to be given. -![Example Spend Community Pool Poll](../../.gitbook/assets/2020-12-21-3.13.51.png) +![](../../.gitbook/assets/image%20%28213%29.png) | Fields | Description | Type | | :--- | :--- | :--- | @@ -110,5 +193,13 @@ Proposals relating to spending the accrued MIR tokens in the community pool can | Recipient | Grant recipient address | Required | | Amount | Grant amount \(in units of MIR\) | Required | +#### 2. Text Poll +The function of the text proposal is to allow proposals that do not fit the defined categories. Given that it is a basic text proposal, simple fields for the `Title`, `Description`, and an `Information Link` for additional information. + +| Field | Description | Type | +| :--- | :--- | :--- | +| Title | Title of the poll | Required | +| Description | Short description of the poll | Required | +| Information Link | External URL for further information | Optional | diff --git a/protocol/mirror-token-mir.md b/protocol/mirror-token-mir.md index 1108ccd..04ef98d 100644 --- a/protocol/mirror-token-mir.md +++ b/protocol/mirror-token-mir.md @@ -1,6 +1,6 @@ # Mirror Token \(MIR\) -The Mirror Token \(MIR\) is Mirror Protocol's governance token. Currently, it must be staked to vote on active polls and is required as a deposit for making new governance polls. In future iterations of Mirror, it will serve further purposes for the protocol that increase its utility and value. +The **Mirror Token \(MIR\)** is Mirror Protocol's governance token. Currently, it must be staked to vote on active polls and is required as a deposit for making new governance polls. In future iterations of Mirror, it will serve further purposes for the protocol that increase its utility and value. Users that stake MIR tokens also earn MIR rewards generated from withdrawing collateral from CDP positions within the protocol. @@ -45,19 +45,51 @@ The distribution structure at the end of year 4 will look like the below: #### **Distribution Rate \(Inflation\)** -Inflation rate of MIR tokens are designed to gradually decrease every year, until it reaches 370.575M at the end of year 4. After the end of year 4, no more MIR tokens will be minted through inflation. +Inflation rate of MIR tokens are designed to gradually decrease every year until it reaches 370.575M at the end of year 4. After the end of year 4, no more MIR tokens will be minted through inflation. -## Staking Rewards +## MIR Staking Rewards {% hint style="info" %} -This section discusses staking rewards for MIR tokens, which come from trading fees used to buy back MIR from the market. Staking LP tokens also generates MIR rewards, which come directly from new MIR tokens created every block. Learn more about it [here](lp-token.md#from-staking). +This section discusses staking rewards for MIR tokens, which come from trading fees used to buy back MIR from the market. Staking LP and sLP tokens also generate MIR rewards, which come directly from new MIR tokens created every block. Learn more about it [here](staking-tokens-lp-and-slp.md#staking-rewards). {% endhint %} ### From Protocol Fees -MIR Token stakers receive MIR token rewards every block, which are generated from [protocol fees](mirrored-assets-massets.md#protocol-fee) from CDP withdrawals. The protocol fees are collected from CDP collateral and are sold for TerraUSD to buy MIR through Terraswap. The MIR tokens are then distributed as rewards to MIR stakers in proportion to the percentage of total stake. This process balances the generation of new MIR by creating buying pressure. +MIR Token stakers receive MIR token rewards every block which [protocol fees](mirrored-assets-massets.md#protocol-fee) are generated from CDP withdrawals. The protocol fees are collected from CDP collateral and are sold for TerraUSD to buy MIR through Terraswap after being sent to the [Collector ](../contracts/collector.md)contract. The MIR tokens are then distributed as rewards to MIR stakers and voters in proportion to the percentage of total stake. This process balances the generation of new MIR by creating buying pressure. ### From Poll Creation Fees -Whenever a new governance poll is created, an initial deposit of MIR tokens must be paid. If the poll does not reach voting quorum, this deposit is distributed to all MIR stakers proportionately. +Whenever a new governance poll is created, an initial deposit of MIR tokens must be paid. If the poll does not reach the voting quorum, this deposit is distributed to all MIR stakers proportionately. + +### From Voting Rewards + +From protocol fee and poll creation fees from polls that have not reached voting quorum, `voter_weight` is used to determine the amount of MIR tokens that are distributed among users who voted on on-going polls. If total MIR governance reward which includes both staking and voting rewards is $$R_{\text{total}}$$ is, + +$$ +R_{\text{passive}}+R_{\text{vote}} +$$ + +where $$R_{\text{passive}}$$is the reward for MIR stakers that did not vote, and $$R_{\text{vote}}$$is the reward for users that have voted on on-going polls. If `voter_weight` is $$W_{\text{vote}}$$, and each individual and total number of MIR voted for the $$i$$th poll are $$m_{\text{i}}$$ and $$M_{\text{i}}$$,the voting reward $$R_{\text{vote}}$$ is, + +$$ +\sum_{i=1}^n \frac{m_{\text{i}}}{M_{\text{i}}} \frac{W_{\text{vote}}{R_{\text{gov}}}}{n} +$$ + +### APR Calculation + +{% hint style="warning" %} +**Note** Since protocol fees for most mAssets are only generated during trading hours of their underlying real-world asset, the actual reward distributed over the weekends and holidays will be much lower. +{% endhint %} + +Mirror Web App displays the annual percentage rate for MIR staking reward. Due to fluctuating nature of protocol fees, MIR staking APR calculation uses the **average reward per day from the last 15 days**. + +If reward for MIR staker on day $$i$$ is $$r_i$$, with total MIR staked amount is $$M$$, annualized percentage rate for MIR staking \(365 days\) would be, + +$$ +\frac{\sum_{i=1}^{15}m_i}{M}\times365 +$$ + +where reward distribution information of the last 15 days is applied. This APR is calculated under the assumption that the users have voted on all on-going governance proposals. + + diff --git a/protocol/mirrored-assets-massets.md b/protocol/mirrored-assets-massets.md index 793418c..73c8549 100644 --- a/protocol/mirrored-assets-massets.md +++ b/protocol/mirrored-assets-massets.md @@ -2,7 +2,7 @@ mAssets are blockchain tokens that behave like "mirror" versions of real-world assets by reflecting the exchange prices on-chain. They give traders the price exposure to real assets while enabling fractional ownership, open access and censorship resistance as any other cryptocurrency. -{% hint style="warning" %} +{% hint style="info" %} Unlike traditional tokens which serve to represent a real, underlying asset, mAssets are purely synthetic and only capture the price movement of the corresponding asset. {% endhint %} @@ -14,9 +14,9 @@ An mAsset can be described by the following properties: Describes the underlying asset the mAsset is supposed to track. -### Minimum Collateral Ratio +### Minimum Collateral Ratio & Multiplier -A CDP that mints the mAsset cannot have a collateral ratio below this value, lest it be subject to liquidation through auction. +A CDP that mints the mAsset cannot have a collateral ratio below **minimum collateral ratio** times the **multiplier** parameter, lest it be subject to liquidation through auction. A multiplier is a parameter assigned to each asset type that could be used as collateral to open a CDP and is multiplied to the minimum collateral ratio of the minted mAsset to determine the final minimum collateral ratio for the given position. ### Auction Discount Rate @@ -32,7 +32,7 @@ For instance, the price feed is halted when real-world markets for the asset are ### Oracle Feeder -The **Oracle Feeder** is a Terra account that can change the registered on-chain price for an mAsset. They are responsible for reporting an accurate and up-to-date price, so that the mAsset's trading value is kept in sync with its reflected asset. Each mAsset has its own dedicated feeder, which can be reassigned through governance. The oracle feeders for the genesis mirrored assets are owned by [Band Protocol](https://www.bandprotocol.com), but the community can assign oracle feeders to other providers to newly whitelisted assets through governance. +The **Oracle Feeder** is a Terra account that can change the registered on-chain price for an mAsset, whitelisted collateral, and staking reward distribution between LP and sLP based on current price premium of mAssets. They are responsible for reporting an accurate and up-to-date price, so that the mAsset's trading value is kept in sync with its reflected asset. Each mAsset has its own dedicated feeder, which can be reassigned through governance. The oracle feeders for the genesis mirrored assets are owned by [Band Protocol](https://www.bandprotocol.com/), but the community can \(re-\)assign oracle feeders to other providers to newly whitelisted assets through governance. ## Lifecycle @@ -44,50 +44,88 @@ To **whitelist** an mAsset is to register it with Mirror Protocol, which involve * creating the mAsset-UST trading pair on Terraswap and its LP token * registering the new mAsset with all relevant Mirror Contracts -Whitelisting is approved by governance and is automatically implemented if the whitelisting poll receives enough votes. Once an mAsset has been whitelisted, it will be mintable through opening a CDP and tradeable on Terraswap. In addition, LP tokens for the corresponding Terraswap pool will begin to earn MIR inflation rewards when staked. +Whitelisting is approved by [governance](governance/whitelist-procedure.md) and is automatically implemented if the whitelisting poll receives enough votes. Once an mAsset has been whitelisted, it will be mintable through opening a CDP and tradeable on Terraswap. In addition, LP tokens for the corresponding Terraswap pool will begin to earn MIR inflation rewards when staked. ### Delisting & Migration In situations where the tracked asset undergoes a corporate event such as a stock split, merger, bankruptcy, etc. and becomes difficult to reflect properly due to inconsistencies, an mAsset can be **delisted**, or discontinued, with the following migration procedure initiated by the oracle feeder: +In situations where the tracked asset undergoes a corporate event such as a stock split, merger, bankruptcy, etc. and becomes difficult to reflect properly due to inconsistencies, an mAsset can be **delisted**, or discontinued, with the following migration procedure initiated by the oracle feeder: + 1. New replacement mAsset token, Terraswap pair, and LP tokens contracts are created, and the present values of properties of mAsset will be transferred over -2. The oracle feeder sets the "end price" for the mAsset to the latest valid price +2. The oracle feeder sets the `end_price` for the mAsset to the latest valid price 3. The mAsset's min. collateral ratio is set to 100% At this stage: * CDPs may no longer mint new tokens of the mAsset * Liquidation auctions are disabled for the mAsset -* Burns will take effect at the fixed "end price" for withdrawing collateral from any existing mint position. -* LP tokens for the mAsset will stop counting for staking rewards +* Burns will take effect at the fixed `end_price` for withdrawing collateral from any existing mint position. +* LP & sLP tokens for the mAsset will stop counting for staking rewards -Delisting will not directly affect the functionality of the mAsset's Terraswap pool and users will still be able to make trades against it, although price is likely to be very unstable. Due to the possible price instability, trading against the Terraswap pool will be blocked from the web frontend interface. +Delisting will not directly affect the functionality of the mAsset's Terraswap pool and users will still be able to make trades against it, although price is likely to be very unstable \(and the [Web App](../user-guide/getting-started/) will not provide front-end interface for trading of delisted mAsset\). Users are urged to burn the mAsset to recover collateral from any open positions on Mirror Protocol, including their own. -Users are urged to burn the mAsset to recover collateral _from any open positions_ on Mirror Protocol, including their own. Since anyone can burn against any open position, CDP holders may end up having none or less amount of "minted assets" within their position, but they will still be able to withdraw remaining amount of collateral by only burning the remaining amount of delisted mAsset. Opening a new CDP / engaging in liquidity provision can be done with the new, replacement mAsset. +Since anyone can burn against any open position, CDP holders may end up having no or less amount of "borrowed assets" within their position, but they will still be able to withdraw the remaining amount of collateral by only burning the remaining amount of delisted mAsset. Opening a new CDP / engaging in liquidity provision can be done with the new, replacement mAsset. The old mAsset will be retired and marked as "**delisted**", only allowing burn, close CDP, withdraw collateral and liquidity, and unstake LP transactions on front-end interfaces. +Opening a new CDP / engaging in liquidity provision can be done with the new, replacement mAsset. The old mAsset will be retired and marked as `delisted` only allowing burn, close CDP, withdraw collateral and liquidity, and unstake LP transactions on front-end interfaces. + +### Pre-IPO + +When an IPO schedule and price quote has been announced, a new mAsset can be whitelisted as a **pre-IPO** mAsset to be minted and traded on Mirror Protocol upon passing of a [governance poll](governance/pre-ipo-procedure.md). Whitelisting of pre-IPO mAsset is different from a regular whitelisting \(explained above\) operation in the following manner: + +* Creating the pre-IPO token and assigning a fixed price to be fed during the mint period +* Assigning a mint period that allows minting of pre-IPO mAssets within its duration +* Assigning a collateral ratio to be only effective during the mint period +* When mint period ends, pre-IPO assets will no longer be mintable, until the IPO event + +When IPO occurs, + +* [Oracle](../contracts/oracle.md) triggers the IPO event on Mirror Protocol +* The asset becomes mintable again at the oracle price of the underlying asset +* A new collateral ratio, defined by the Pre-IPO poll proposer is assigned + ## Collateralized Debt Position -New tokens for a listed mAsset can be minted by creating a **collateralized debt position** \(CDP\) with either TerraUSD \(UST\) or other mAsset tokens as collateral. The CDP is essentially a short position against the price movement of the reflected asset, -- i.e. if the stock price of AAPL rises, minters of mAAPL would be pressured to deposit more collateral to maintain the same collateral ratio. +New tokens for a listed mAsset can be minted by creating a **collateralized debt position** \(CDP\) with either TerraUSD \(UST\), mAsset or whitelisted collateral tokens as collateral. Also, mAssets can be directly shorted upon opening a CDP to mint sLP tokens. The CDP is essentially a short position against the price movement of the reflected asset, -- i.e. if the stock price of AAPL rises, minters of mAAPL would be pressured to deposit more collateral to maintain the same collateral ratio. + +### Collateral + +Mirror Protocol accepts the following types of tokens as collateral: + +* UST +* All mAssets +* Other collateral: LUNA, MIR, ANC, aUST + +Each type of asset listed above has a different `multiplier` \($$\zeta$$\) which is multiplied to the minimum collateral ratio of each minted mAsset. + +| Asset | Multiplier | +| :--- | :--- | +| MIR | 1.3333334 | +| ANC | 1.3333334 | +| LUNA | 1.3333334 | +| aUST | 1 | + +For example, if LUNA, which has a collateral premium of 1.333334, is used as collateral to mint mAAPL, which has a minimum collateral ratio of 150%, then the minimum tolerated collateral ratio for this position will be $$1.3333334\times150\% \approx 200\%$$. Any price change of either LUNA or mAAPL which causes collateral ratio drop to below 200% will lead to liquidation auction. ### Collateral Ratio The **collateral ratio** \(C-ratio\) is simply the ratio of the value of a CDP's locked collateral to the value of its current minted tokens. -The CDP is required to always maintain a C-ratio above the mAsset's minimum, otherwise the protocol will initiate a margin call to liquidate collateral in an attempt to restore the position's C-ratio. The protocol is able to determine whether a position is underneath the required threshold by re-denominating all mAsset values into UST via their oracle-reported prices. +The CDP is required to always maintain a C-ratio above the position's minimum, otherwise the protocol will initiate a margin call to liquidate collateral. The protocol is able to determine whether a position is underneath the required threshold by re-denominating all mAsset values into UST via their oracle-reported prices. -Let the mAsset's minimum C-ratio be $$r_{\text{min}}$$. Given a CDP's current quantities of collateral and minted mAssets $$Q_c,Q_m$$ and their current prices $$P_c, P_m$$, the effective collateral ratio at any time $$t$$ is: +Let the mAsset's minimum C-ratio and collateral's multiplier be each $$r_{\text{min}}$$and $$\zeta$$. Given a CDP's current quantities of collateral and minted mAssets $$Q_c,Q_m$$ and their current prices $$P_c, P_m$$, the effective collateral ratio at any time $$t$$ is: $$ r_t = \frac{P_cQ_c}{P_mQ_m} $$ -A CDP should strive to always maintain $$r_{t} \ge r_{\text{min}}$$, otherwise the collateral will be subject to [liquidation](mirrored-assets-massets.md#liquidation-and-auction). +A CDP should strive to always maintain $$r_{t} \ge \zeta r_{\text{min}}$$, otherwise the collateral will be subject to [liquidation](mirrored-assets-massets.md#liquidation-and-auction). #### Opening a new position -Users are allowed to set the initial C-ratio for their CDPs as long as it meets or exceeds the mandated minimum value for each mAsset. The selection of the initial C-ratio $$r_{0}$$ along with the choice of collateral is used to determine how many tokens are minted during the creation of a CDP. +Users are allowed to set the initial C-ratio for their CDPs as long as it meets or exceeds the mandated minimum value for each position. The selection of the initial C-ratio $$r_{0}$$ along with the choice of collateral is used to determine how many tokens are minted during the creation of a CDP. $$ Q_{m} = \frac{P_{c}Q_{c}}{r_{0}P_{m}} @@ -97,31 +135,31 @@ $$ With an existing CDP, the user can deposit additional collateral $$Q_c'$$ to raise its effective C-ratio. The total amount of potential mintable mAsset tokens is then increased by the marginal value $$Q_m'$$. -$$Q_c'$$ can be negative, which is equivalent to withdrawing collateral. The user can only withdraw up to however much is needed to maintain the mAsset's effective C-ratio above the mAsset's minimum. The user will receive $$Q_c' - \text{fee}_{\text{protocol}}$$ upon withdrawal due to the [protocol fee](mirrored-assets-massets.md#protocol-fee). +$$Q_c'$$ can be negative, which is equivalent to withdrawing collateral. The user can only withdraw up to however much is needed to maintain the mAsset's effective C-ratio above the $$\zeta r_{\text{min}}$$. The user will receive $$Q_c' - \text{fee}_{\text{protocol}}$$ upon withdrawal due to the [protocol fee](mirrored-assets-massets.md#protocol-fee). $$ -Q_m + Q_{m}' = \frac{P_{c}(Q_{c}+Q_{c}')}{r_\text{min}P_{m}} +Q_m + Q_{m}' = \frac{P_{c}(Q_{c}+Q_{c}')}{\zeta r_\text{min}P_{m}} $$ #### Minting / Burning mAssets -In addition to depositing and withdrawal collateral, the user can also mint and burn mAssets against the CDP to adjust the value of their CDP's effective C-ratio. +In addition to depositing and withdrawal collateral, the user can also mint and burn mAssets against the CDP to adjust the value of their CDP's effective C-ratio. Let the quantity of newly minted tokens be $$Q_m'$$\(negative if burned\). The minimum collateral required to keep the CDP position above the mAsset's min. collateral ratio is: $$ -Q_c \ge \frac{r_\text{min} P_m (Q_m+Q_m')}{P_c} +Q_c \ge \frac{\zeta r_\text{min} P_m (Q_m+Q_m')}{P_c} $$ Anything above that amount can be withdrawn from the CDP. #### Closing a position -If a user wishes to collect all their collateral from their CDP, they must close their position by returning the outstanding balance of minted mAssets, which the protocol will burn. The user will be then be able to withdraw their locked collateral. +If a user wishes to collect all their collateral from their CDP, they must close their position by returning the outstanding balance of minted mAssets, which the protocol will burn. A user must first hold the corresponding amount of mAsset to close CDP \(any sLP tokens minted are automatically burned when mAssets are returned\). The user will then be able to withdraw their locked collateral minus the protocol fee. ### Protocol Fee -The Mirror **protocol fee** is charged whenever a withdrawal from a CDP is made \(including closing the position\). This fee is then converted into MIR through Terraswap and distributed to MIR token stakers as a staking reward. +1.5% Mirror **protocol fee** is charged whenever a withdrawal from a CDP is made \(including position closure and liquidation auction\). The protocol fee is calculated based on the value of the collateral at position opening. This fee is then sent to the [Collector](../contracts/collector.md) contract, converted into MIR through Terraswap and distributed to MIR token stakers as a staking reward. ### Margin Call & Auction diff --git a/protocol/staking-tokens-lp-and-slp.md b/protocol/staking-tokens-lp-and-slp.md new file mode 100644 index 0000000..c2c97fc --- /dev/null +++ b/protocol/staking-tokens-lp-and-slp.md @@ -0,0 +1,130 @@ +# Staking Tokens \(LP & sLP\) + +## LP Tokens + +**LP Tokens** are given to **L**iquidity **P**roviders when they add liquidity to mAsset-UST or MIR-UST Terraswap pools. Each pool has a unique LP token associated with it and cannot be combined with LP tokens from other pools. They serve primarily as a unit of account, representing the liquidity provider's share in the pool in order to reclaim assets when they remove liquidity. + +Although LP tokens exist independently as a yield-generation feature of Terraswap, they are central to Mirror's market infrastructure. As such, the protocol provides MIR rewards to users who stake LP tokens as an incentive to help maintain liquid markets on Terraswap for mAssets and MIR. + +{% hint style="info" %} +There exists a different LP token for each mAsset-UST's Terraswap pool, as well as the MIR-UST pool. The descriptions below refer to each individual pool's supply of LP tokens. +{% endhint %} + +### Minting + +A user can provide liquidity by depositing tokens to both sides of a Mirror-related Terraswap pool. This results in the creation of LP tokens for that pool, which they can use to retrieve assets from the pool. + +#### Creating a new pool + +For a new pool with starting quantities of UST and mAsset / MIR $$x_0,y_0$$, the number of LP tokens is: + +$$ +\text{LP} = \sqrt{x_0 y_0} +$$ + +#### Adding to an existing pool + +Given quantities of UST and mAsset/MIR being deposited$$A_{\text{in}},B_{\text{in}}$$, and currently in the pool prior to deposit$$X,Y$$, and the current supply of LP tokens $$\text{LP}_{\text{total}}$$, the amount of newly minted LP tokens is: + +$$ +\text{LP}_{\text{new}} = \min\bigg(\frac{A_{\text{in}}}{X}\text{LP}_{\text{total}}, \frac{B_{\text{in}}}{Y}\text{LP}_{\text{total}}\bigg) +$$ + +Although liquidity providers can deposit any amount for both tokens, they are incentivized to put in quantities where value is equal on both sides, taking into consideration the mAsset or MIR's market price. Doing otherwise would cause them to incur losses as it would create arbitrage opportunities against the pool, and the LP tokens they received would be insufficient for recover their liquidity. + +### Burning + +{% hint style="warning" %} +It is very probable that the amounts of assets recovered by burning LP tokens will be different from the quantities deposited. This comes from a variety of reasons such as price movement of mAsset / MIR, changes in your relative share of the liquidity pool, etc. +{% endhint %} + +A user can burn their LP tokens to recover their deposited liquidity. The pool will send back amounts of UST and mAssets \(or MIR\), depending on the amount of LP tokens they burn, determined by the formulas shown below. + +$$ +A_{\text{out}} = \frac{\text{LP}_{\text{burn}}}{\text{LP}_{\text{total}}}X +$$ + +$$ +B_{\text{out}} = \frac{\text{LP}_{\text{burn}}}{\text{LP}_{\text{total}}}Y +$$ + +### LP Commission Rewards + +Holders of LP tokens receive a portion of rewards generated by the pool's trading fees, divvied out in proportion to total share of LP token pool. A portion of either mAsset/MIR or UST \(depending on the direction of the trade\) gets added back into the pool as the[ **LP Commission**](terraswap.md#lp-commission)**.** + +This functionality is not implemented in the Mirror Protocol contracts, and comes purely due to Terraswap's incentive structure for liquidity providers. Because the trading fee rewards are returned to the pool, they can only be withdrawn by burning LP tokens and withdrawing liquidity. + +## sLP Tokens \(Short Tokens\) + +**sLP Tokens** are minted and immediately staked when a short position is created. Each mAsset has a unique sLP token associated with it and cannot be combined with sLP from other mAssets. When closing a short CDP, the same amount of both sLP and mAsset have to be burned in order to fully close the short position and withdraw all collateral. Note that sLP cannot be transferred or traded, and they are immediately staked after being minted and burned immediately after a position is closed. + +### Minting + +A user can short an mAsset by providing collateral to mint contract. This results in the creation of sLP tokens, which can be burnt with the corresponding mAsset to retrieve the collateral. + +The number of sLP minted is directly proportional to the quantity of mAssets minted and shorted from the position. A user will also receive the quantity of UST corresponding to the Terraswap value of the shorted mAsset after a governance-defined locking period. The locking period parameter in Mirror Lock contract and is changeable through governance poll voting. + +### Burning + +In order to fully burn sLP tokens to withdraw all collateral, a user must have hold the amount of mAssets that were shorted when the short position was created. + +When the position is closed, sLP token will be automatically unstaked, and be burnt with the mAsset against the short position to redeem all collateral. Note that short position is similar to the typical mint position, so a 1.5% protocol fee will also be charged on the amount of collateral being withdrawn. + +If the whole position is closed, the minter immediately receives back locked UST. If the position is only partially closed, the UST received from the automatic sell-off of the minted mAsset is still subject to the total locking period. + +### Lock Period + +Since minted mAssets are sold immediately after short position creation, amount of UST corresponding to the value of mAsset shorted against the Terraswap pool is returned to the user. But if the user is able to immediately buy back the corresponding amount of mAssets with the UST returned from shorting, the original purpose of sLP tokens reward to eliminate the price premium between Terraswap and Oracle price is likely to fail. + +Therefore, a **`lock_period`** is applied to the returned UST after a short position is created \(set to 15 days at the launch of Mirror v2\). As returned UST is locked for a defined period of time, users must wait to buy back the corresponding amount of mAsset to close their short position, which increases the chance to make the premium converge closer to 0% during that period of time. + +## Staking Rewards + +{% hint style="info" %} +This section discusses staking rewards for LP & sLP tokens, which come from the new MIR tokens minted per block by the protocol as inflation. Staking MIR also generates MIR rewards, which come from trading fees rather than inflation. Learn more about it [here](mirror-token-mir.md#staking-rewards). +{% endhint %} + +Mirror allows users to additionally profit from LP tokens by staking them to receive Mirror Token \(MIR\) rewards. The LP tokens can be unstaked at any time, and then burned to retrieve the corresponding deposited liquidity and LP Commission rewards. + +Users can additionally profit from sLP tokens by staking them to receive Mirror Token \(MIR\) rewards. The sLP tokens can be unstaked and burned \(with the minted mAsset\) anytime to retrieve the corresponding amount of collateral. + +Mirror Protocol distributes rewards to each mAsset staking pools in [Staking contract](../contracts/staking.md) based on the `weight` parameter of each mAsset. mAsset pools as well as the MIR pool. All mAsset-UST staking pools receive a weight of 1, while the MIR pool receives a weight of 3. Therefore, there is a stronger reward incentive to stake to MIR pool as they confer 3 times the reward when staked relative to mAssets. + +Within each mAsset's staking pool, MIR tokens are distributed to LP and sLP stakers, where sLP tokens reward weight can increase up to 40%, based on the current price premium between Terraswap and Oracle [price](mirrored-assets-massets.md#price). When enough short positions are created to lower the price premium, sLP reward weight will decrease, which automatically increases LP reward weight up to 100%. Below is the table of short reward distribution based on price premium: + +| Premium | Short Ratio | Premium | Short Ratio | +| :--- | :--- | :--- | :--- | +| 0 | 0.0091001 | 3.25 | 0.3577401 | +| 0.25 | 0.0160237 | 3.5 | 0.3732771 | +| 0.5 | 0.0267229 | 3.75 | 0.3839763 | +| 0.75 | 0.0422599 | 4 | 0.3909000 | +| 1 | 0.0634621 | 4.25 | 0.3951102 | +| 1.25 | 0.0906509 | 4.5 | 0.3975161 | +| 1.5 | 0.1234150 | 4.75 | 0.3988081 | +| 1.75 | 0.1605175 | 5 | 0.3994600 | +| 2 | 0.2000000 | 5.25 | 0.3997692 | +| 2.25 | 0.2394825 | 5.5 | 0.3999070 | +| 2.5 | 0.2765850 | 5.75 | 0.3999646 | +| 2.75 | 0.3093491 | 6 | 0.3999873 | +| 3 | 0.3365379 | 6.25 | 0.3999957 | + +The MIR reward, $$R_{k}$$for a specific staking pool corresponding to the asset $$k$$ with weight $$w_k$$ and quantity $$m$$ of MIR introduced into circulation, is given by: + +$$ +R_{k}=\frac{w_{k}}{\sum_{i=1}^n{w_{i}}}m +$$ + +The reward for LP staking pool, based on the current short reward ratio$$r_{s}$$ is: + +$$ +(1-r_s)\frac{w_{k}}{\sum_{i=1}^n{w_{i}}}m +$$ + +The reward for sLP staking pool, based on the current short reward ratio$$r_{s}$$ is: + +$$ +r_s\frac{w_{k}}{\sum_{i=1}^n{w_{i}}}m +$$ + +A user will receive the portion of rewards for their pool equivalent to their proportional share of staked LP and sLP for that pool. + diff --git a/protocol/synopsis.md b/protocol/synopsis.md index d50fbdb..280af2c 100644 --- a/protocol/synopsis.md +++ b/protocol/synopsis.md @@ -5,7 +5,7 @@ In Mirror Protocol, users act in one or more of the following roles: * Trader -* Minter +* Minter & Shorter * Liquidity Provider * Staker @@ -17,19 +17,22 @@ In addition, there are special auxiliary agents that are required for Mirror's i A **trader** engages in buying and selling mAssets against UST through [Terraswap](terraswap.md) and benefits from price exposure via mAssets. -### Minter +### Minter & Shorter -A **minter** is a user that enters into a [collateralized debt position](mirrored-assets-massets.md#collateralized-debt-position) \(CDP\) in order to obtain newly minted tokens of an mAsset. CDPs can accept collateral in either UST or mAssets, and must maintain a collateral ratio above the mAsset's minimum \(set by governance\). Therefore, minters effectively take a short position against the reflected asset's price direction, and takes a neutral position when collateralizing the position in UST or a long position when collateralizing in another mAsset. +A **minter** is a user that enters into a [collateralized debt position](mirrored-assets-massets.md#collateralized-debt-position) \(CDP\) in order to obtain newly minted tokens of an mAsset. CDPs can accept collateral in the form of UST, mAssets, or whitelisted collateral and must maintain a collateral ratio above the mAsset's minimum multiplied by a premium rate for each collateral type \(set by governance\). -Collateral can be withdrawn as long as the CDP's collateral ratio remains above the minimum. Minters can adjust the CDP's collateral ratio by burning mAssets or depositing more collateral. +A **shorter** is a user that enters into the same CDP but to sell the minted tokens immediately and get newly minted [sLP tokens](staking-tokens-lp-and-slp.md#slp-tokens-short-tokens). sLP token can be staked to earn MIR reward when there is a price premium for Terraswap price compared to the oracle price. + +Therefore, shorters effectively take a short position against the reflected asset's price direction. +Excess collateral can be withdrawn as long as the CDP's collateral ratio remains above the minimum. Minters can adjust the CDP's collateral ratio by burning mAssets or depositing more collateral. ### Liquidity Provider -A **liquidity provider** adds equal amounts of an mAsset and UST to the corresponding Terraswap pool, which increases liquidity for that market. This process rewards the liquidity provider newly minted [LP tokens](lp-token.md), which represent the liquidity provider's share in the pool and also provide rewards from the pool's trading fees. LP tokens can be burned to reclaim the share of mAssets and UST from the pool. +A **liquidity provider** adds equal amounts of an mAsset and UST to the corresponding Terraswap pool, which increases liquidity for that market. This process rewards the liquidity provider newly minted [LP tokens](staking-tokens-lp-and-slp.md#lp-tokens), which represent the liquidity provider's share in the pool and also provide rewards from the pool's trading fees. LP tokens can be burned to reclaim the share of mAssets and UST from the pool. ### Staker -A **staker** is a user that stakes either LP Tokens \(with the Staking contract\) or [MIR tokens](mirror-token-mir.md) \(with the Gov contract\) in order to earn staking rewards as MIR tokens. Whereas LP token stakers earn rewards from new MIR tokens from inflation, MIR token earn staking rewards from CDP withdrawal fees. +A **staker** is a user that stakes either LP tokens or sLP tokens \(with the [Staking contract](../contracts/staking.md)\) or MIR tokens \(with the [Gov contract](../contracts/gov.md)\) in order to earn staking rewards as MIR tokens. Whereas LP and sLP token stakers earn rewards from new MIR tokens from inflation, MIR token stakers earn staking rewards from CDP withdrawal fees. If the user has staked MIR tokens, they are eligible to participate in governance and receive voting power weighted by the amount of their total staked MIR. [Governance](governance/) is the process through which new mAssets get whitelisted and protocol parameters can be altered. @@ -37,7 +40,7 @@ LP Tokens can be unstaked at any time, but MIR tokens can only be unstaked when ### Oracle Feeder -An **oracle feeder** is a designated Terra account responsible for providing an accurate and up-to-date price feed for a specific mAsset and is the sole party that is permitted to update the registered reported price of the reflected asset. Because of its crucial role in the operational stability of mAssets, the oracle feeder is elected through governance and will be swiftly replaced by the community if ever it underperforms in its duties. +An **oracle feeder** is a designated Terra account responsible for providing an accurate and up-to-date price feed for a specific mAsset or whitelisted collateral and is the sole party that is permitted to update the registered reported price of the reflected asset. Because of its crucial role in the operational stability of mAssets, the oracle feeder is elected through governance and will be swiftly replaced by the community if ever it underperforms in its duties. ## Tokens @@ -47,6 +50,7 @@ There are several tokens involved in Mirror Protocol: | :--- | :--- | :--- | | TerraUSD \(UST\) | Stablecoin | Native Terra asset | | [Mirrored Assets](mirrored-assets-massets.md) \(mAssets\) | Synthetic Asset | Terraswap CW20 Token | -| [LP Tokens](lp-token.md) | Staking | Terraswap CW20 Token | | [Mirror Token](mirror-token-mir.md) \(MIR\) | Staking, Governance | Terraswap CW20 Token | +| [LP Tokens](staking-tokens-lp-and-slp.md#lp-tokens) | Staking | Terraswap CW20 Token | +| [sLP Tokens](staking-tokens-lp-and-slp.md#slp-tokens-short-tokens) | Staking | Terraswap CW20 Token | diff --git a/protocol/terraswap.md b/protocol/terraswap.md index 7b0d6aa..d9dd5b5 100644 --- a/protocol/terraswap.md +++ b/protocol/terraswap.md @@ -8,7 +8,7 @@ Terraswap is a [Uniswap](https://uniswap.org)-inspired automated market marker \ ### Liquidity Pools -Terraswap creates automated markets for pairs of tokens \(or native Terra coins like UST\) called **pools** which enable users to exchange one asset for the other directly on-chain. Pools maintain balances of both assets, to which users can provide liquidity in exchange for reward-bearing LP tokens. A more detailed explanation about LP tokens and their relationship with Mirror can be found [here](lp-token.md). +Terraswap creates automated markets for pairs of tokens \(or native Terra coins like UST\) called **pools** which enable users to exchange one asset for the other directly on-chain. Pools maintain balances of both assets, to which users can provide liquidity in exchange for reward-bearing LP tokens. A more detailed explanation about LP tokens and their relationship with Mirror can be found [here](). ### Constant Product diff --git a/security.md b/security.md index 03410e4..df3b0a4 100644 --- a/security.md +++ b/security.md @@ -6,7 +6,8 @@ The security of the Mirror protocol is our highest priority; our development tea ## Audits -* [Mirror Smart Contract Audit](https://docsend.com/view/p4es2dgvwadamgqg) by Cyber Unit +* [Mirror v1 Smart Contract Audit](https://docsend.com/view/p4es2dgvwadamgqg) by **Cyber Unit** +* Mirror v2 Smart Contract Audit by **Cryptonics \(TBD\)** ## Bug Bounty Program @@ -24,13 +25,13 @@ The primary scope of the bug bounty program is for vulnerabilities affecting the Vulnerabilities in contracts built on top of the protocol by third-party developers \(such as smart contract wallets\) are not in-scope, nor are vulnerabilities that require ownership of an admin key. -The secondary scope of the bug bounty program is for vulnerabilities affecting the Mirror interface hosted at [https://terra.mirror.finance](https://terra.mirror.finance) that could conceivably result in exploitation of user accounts. +The secondary scope of the bug bounty program is for vulnerabilities affecting the Mirror interface hosted at [https://terra.mirror.finance](https://terra.mirror.finance) that could conceivably result in the exploitation of user accounts. Finally, test contracts \(Tequila and other testnets\) and staging servers are out of scope, unless the discovered vulnerability also affects the Mirror Protocol or Interface, or could otherwise be exploited in a way that risks user funds. **Disclosure** -Submit all bug bounty disclosures to [security@mirror.finance](mailto:security@Mirror.finance). The disclosure must include clear and concise steps to reproduce the discovered vulnerability in either written or video format. Mirror will follow up promptly with acknowledgement of the disclosure. +Submit all bug bounty disclosures to [security@mirror.finance](mailto:security@Mirror.finance). The disclosure must include clear and concise steps to reproduce the discovered vulnerability in either written or video format. Mirror will follow up promptly with acknowledgment of the disclosure. **Terms and Conditions** diff --git a/user-guide/getting-started/claim-mir-reward.md b/user-guide/getting-started/claim-mir-reward.md new file mode 100644 index 0000000..7ef150a --- /dev/null +++ b/user-guide/getting-started/claim-mir-reward.md @@ -0,0 +1,26 @@ +# Claim MIR Reward + +MIR reward is generated in three different ways on Mirror Protocol: + +1. Long Farm \(Stake LP Tokens\) +2. Short Farm \(Create Short position\) +3. Voting Reward \(From voting on governance polls that are in progress\) + +Although reward is distributed in three different channels, they are all claimable by executing one transaction from **My Page.** + +1 . Navigate to **My Page** and click `Claim All Rewards` + +![](../../.gitbook/assets/image%20%28176%29.png) + +2. Check the simulated value, and click on `Claim` button. + +![](../../.gitbook/assets/image%20%28179%29.png) + +3. Station Extension should prompt you to sign the transaction. Confirm the details presented and input your password to sign. + +To see your rewards in more depth, you may navigate to **Farming** or **Govern** tabs to check how much reward is claimable from each category. + +![](../../.gitbook/assets/image%20%28174%29.png) + +![](../../.gitbook/assets/image%20%28207%29.png) + diff --git a/user-guide/getting-started/governance.md b/user-guide/getting-started/governance.md index ec67a8f..175b4e1 100644 --- a/user-guide/getting-started/governance.md +++ b/user-guide/getting-started/governance.md @@ -2,86 +2,78 @@ The **Governance** page displays operations related to MIR staking and creating / voting on polls. For more details regarding the Mirror Governance process, [click here](../../protocol/governance/). -## Stake / Unstake MIR Tokens - -MIR tokens are distributed as reward for staked LP tokens, which are generated when user provides liquidity. [Click here](stake.md) to learn more about staking LP tokens. +## Governance Main -In order to vote on governance polls, MIR must be staked to be used as voting power. +The Governance page displays the following data: -1. Navigate to the [**Governance**](https://terra.mirror.finance/gov) page. The Governance page displays the following data: +![](../../.gitbook/assets/image%20%28182%29.png) -* **Market information about MIR Staking**: Information about current staked MIR in the market, and staking ratio are displayed -* **MIR Staking Position:** MIR staking pool box displays expected APR \(annual percentage rate\) from staking MIR tokens, user's staked and unstaked MIR balances. -* **Poll History**: Each poll has a unique poll ID, poll type \(whitelist or parameter change\), poll result, voting ratio and end time. +* **Market information about MIR Staking**: Information about current staked MIR in the market, staking ratio and maximum APR are displayed. To learn how APR for governance is calculated, refer to [this page](../../protocol/mirror-token-mir.md#mir-staking-rewards). +* **MIR Staking Position:** MIR staking pool box displays user's staked and unstaked MIR balances. +* **Poll History**: Each poll has a unique poll ID, poll type \(whitelist or parameter change\), poll result, voting ratio, and end time. -2. Click **`STAKE`** +## Stake / Unstake MIR Tokens -![](../../.gitbook/assets/image%20%2840%29.png) +MIR tokens are distributed as a reward for staked LP tokens, which are generated when users provide liquidity. [Click here](../../protocol/staking-tokens-lp-and-slp.md#lp-tokens) to learn more about staking LP tokens. -3. Select either **Stake** / **Unstake** +In order to vote on governance polls, MIR must be staked to be used as voting power. -![](../../.gitbook/assets/image%20%2838%29.png) +1. Navigate to the [**Governance**](https://terra.mirror.finance/gov) page and click **`Stake`** -4. Enter amount to Stake or Unstake +![](../../.gitbook/assets/image%20%28130%29.png) -![](../../.gitbook/assets/image%20%2830%29.png) +2. Select either **Stake** / **Unstake** -5. Click **`STAKE`** / **`UNSTAKE`**. Station Extension should prompt you to sign the transaction. Confirm the details presented and input your password to sign. +![](../../.gitbook/assets/image%20%28148%29.png) -![](../../.gitbook/assets/image%20%2867%29.png) +3. Enter amount to Stake or Unstake -## Create Poll +{% hint style="warning" %} +MIR tokens that are voted to on-going governance polls will be unstakable when the voting period is over. +{% endhint %} -1. Navigate to the [**Governance**](https://terra.mirror.finance/gov) page +![](../../.gitbook/assets/image%20%28131%29.png) -![](../../.gitbook/assets/image%20%2851%29.png) +4. Click **`STAKE`** / **`UNSTAKE`**. Station Extension should prompt you to sign the transaction. Confirm the details presented and input your password to sign. -2. Click **`CREATE POLL`** +## Create Poll -![](../../.gitbook/assets/image%20%2843%29.png) +1. Navigate to the [**Governance**](https://terra.mirror.finance/gov) page and click `Create Poll`. -3. Select one of the below: +![](../../.gitbook/assets/image%20%28205%29.png) -* **Whitelist:** Poll to list new mAsset on Mirror Protocol -* **Parameter Change:** Poll to change parameter of a listed mAsset -* **Community Pool:** Poll to request MIR funds from Community Pool +2. Select a [poll type](../../protocol/governance/proposal-types.md) to submit. -![](../../.gitbook/assets/image%20%2820%29.png) +![](../../.gitbook/assets/image%20%28132%29.png) -4. After entering desired inputs, click activated button to confirm. +3. After entering desired inputs, click the activated button to confirm. -![](../../.gitbook/assets/image%20%2839%29.png) +![](../../.gitbook/assets/image%20%28147%29.png) 5. Station Extension should prompt you to sign the transaction. Confirm the details presented and input your password to sign. -![](../../.gitbook/assets/image%20%2861%29.png) - ## Vote on Poll -1. Navigate to the [**Governance**](https://terra.mirror.finance/gov) page - -![](../../.gitbook/assets/image%20%2854%29.png) - -2. Select poll that is `IN PROGRESS` +1. Navigate to the [**Governance**](https://terra.mirror.finance/gov) page and select a poll that is `In Progress`. -![](../../.gitbook/assets/image%20%2845%29.png) +![](../../.gitbook/assets/image%20%28196%29.png) -3. Click **`Vote`** +2. After checking the details of this poll, click **`Vote`** -![](../../.gitbook/assets/image%20%2826%29.png) +![](../../.gitbook/assets/image%20%28204%29.png) -4. Select **YES** or **NO**. +3. Select `YES`, `NO` or `ABSTAIN`, and enter the amount to use as voting power. -![](../../.gitbook/assets/image%20%2831%29.png) +![](../../.gitbook/assets/image%20%28154%29.png) 5. Click **`Submit`** to confirm. Station Extension should prompt you to sign the transaction. Confirm the details presented and input your password to sign. -![](../../.gitbook/assets/image%20%2844%29.png) +## -For every poll to be passed, they must meet the conditions below: + For every poll to be passed, they must meet the conditions below: -* Voting quorum must be greater than or equal to 10% of the total staked MIR. Without meeting this condition, no matter how much portion of the voting power has been voted Yes, the poll is ineffective. -* Over 50% of voting power which is dedicated to the poll must be **Yes** -* Voting period \(number of blocks corresponding to 2 weeks\) has ended -* After the voting period is over and the poll passes, it takes 7 days \(number of blocks corresponding to a week\) for the poll to become effective in the protocol. +* Voting quorum must be greater than or equal to `quorum` \(initially set to 10% on Mainnet\) of the total staked MIR. Regardless of `YES` ratio, the poll will not pass if it does not meet the quorum. +* **YES** votes must be greater than **NO** votes +* Voting period \(number of blocks corresponding to 1 week\) has ended +* After the voting period is over and the poll passes, it takes 1 day \(number of blocks corresponding to a day\) for the poll to become effective in the protocol. diff --git a/user-guide/getting-started/mint-and-burn.md b/user-guide/getting-started/mint-and-burn.md index 11d675c..5562eea 100644 --- a/user-guide/getting-started/mint-and-burn.md +++ b/user-guide/getting-started/mint-and-burn.md @@ -1,82 +1,82 @@ -# Mint +# Borrow -The **Mint** page allows you to mint new tokens of an mAsset by opening a [CDP](../../protocol/mirrored-assets-massets.md#collateralized-debt-position). After creating a position, you can manage it on the [My page](https://terra.mirror.finance/my). +User can **Borrow** newly minted mAssets by providing any collateral accepted in Mirror Protocol and open a [CDP](../../protocol/mirrored-assets-massets.md#collateralized-debt-position). After creating a position, user can manage it on My Page. -When the user withdraws collateral either to manage position's collateral ratio or to close the position, a [Protocol Fee](../../protocol/mirrored-assets-massets.md#protocol-fee) of 1.5% is charged to the amount being withdrawn. +When the user withdraws collateral either to manage position's collateral ratio or to close the position, a[ Protocol Fee](../../protocol/mirrored-assets-massets.md#protocol-fee) of 1.5% is charged to the collateral being withdrawn. Please note that all asset values are calculated based on the reported price from the [oracle feeder ](../../protocol/mirrored-assets-massets.md#oracle-feeder)instead of the Terraswap price. -## Mint \(Open Position\) +## Borrow \(Open Position\) -User may mint new mAsset that is whitelisted on Mirror Protocol, by providing other mAssets or UST as collateral and open a new CDP. The value of user's collateral against the minted asset must be higher than the [minimum collateral ratio](../../protocol/mirrored-assets-massets.md#minimum-collateral-ratio) in order to have the transaction successfully executed. +User may mint new mAsset that is whitelisted on Mirror Protocol, by providing other mAssets , UST or [other tokens](../../protocol/mirrored-assets-massets.md#collateral) as collateral and open a new CDP. The value of user's collateral against the minted asset must be higher than the [minimum collateral ratio](../../protocol/mirrored-assets-massets.md#minimum-collateral-ratio) in order to have the transaction successfully executed. -1. Navigate to the [**Mint**](https://terra.mirror.finance/mint) page +1. Navigate to **Borrow \(Mint\)** page and select an asset to borrow. -![](../../.gitbook/assets/image%20%2863%29.png) +2. Select an asset to use as [collateral](../../protocol/mirrored-assets-massets.md#collateral). -2. Select an asset to use as collateral. You can use UST or another mAsset. +![](../../.gitbook/assets/image%20%28170%29.png) -![](../../.gitbook/assets/image%20%2835%29.png) +3. Select an asset to borrow \(mint\). -3. Select the mAsset to mint +![](../../.gitbook/assets/image%20%28165%29.png) -![](../../.gitbook/assets/image%20%2846%29.png) +4. Enter value in `Collateral` and set the `Collateral ratio`. -4. Set the collateral ratio - -![](../../.gitbook/assets/image%20%2836%29.png) +![](../../.gitbook/assets/image%20%28214%29.png) 5. Click `OPEN`. Station Extension should prompt you to sign the transaction. Confirm the details presented and input your password to sign. -![](../../.gitbook/assets/image%20%2855%29.png) - 6. All Done! -![](../../.gitbook/assets/image%20%2827%29.png) +![](../../.gitbook/assets/image%20%28189%29.png) -Now, the minted position becomes visible on My Page. User may choose the same asset pairs to mint more, but due to changed oracle price of both the collateral and the minted asset, and a different collateral ratio, a completely new CDP will be created instead of combining the values with the previously minted position. These two positions will be identifiable by a position ID, which is displayed as a number. +Now, the borrow position becomes visible on My Page. User may choose the same asset pairs to mint more, but due to changed oracle price of both the collateral and the minted asset, and a different collateral ratio, a completely new CDP will be created instead of combining the values with the previously minted position. These two positions will be identifiable by a position ID, which is displayed as a number. ## Close Position -Any user with an open mint position can always choose to close the position, by “burning” the same type and amount of Mirrored Asset corresponding to an open position. When the minted assets are burned, users can reclaim all of the collaterals that were locked in the position. +Any user with an open borrow or [short position ](pool.md#short)can always choose to close the position, by “burning” the same type and amount of Mirrored Asset corresponding to an open position. When the minted assets are burned, users can reclaim all of the collaterals that were locked in the position. -Please note that user cannot close the position if the user holds minted asset of any amount lower than the amount minted to open a position. User must first obtain the same or a greater amount of minted assets by buying them on “Trade” page or have it sent from a different wallet. +Please note that user cannot close the position if the user holds borrowed asset of any amount lower than the amount minted to open a position. User must first obtain the same or a greater amount of minted assets by buying them on the [Market](trade.md) page or have them sent from a different wallet. -1. Navigate to [**My** **Page**](https://terra.mirror.finance/my) +1. Navigate to **My Page** by clicking on the wallet icon. -![](../../.gitbook/assets/image%20%2815%29.png) +![](../../.gitbook/assets/image%20%28168%29.png) -2. In the Mint section, press the "`...`" under actions +2. In the **Borrowing** section, press the "`Manage`" under actions -![](../../.gitbook/assets/image%20%2824%29.png) +![](../../.gitbook/assets/image%20%28145%29.png) 3. Select `Close Position` and confirm details -![](../../.gitbook/assets/image%20%2848%29.png) +{% hint style="warning" %} +If you do not hold an amount greater than or equal to `Burn Amount` displayed on this page, you must first navigate to **Market** page to buy the corresponding amount. +{% endhint %} -4. Click `CLOSE`. Station Extension should prompt you to sign the transaction. Confirm the details presented and input your password to sign. +![](../../.gitbook/assets/image%20%28167%29.png) -![](../../.gitbook/assets/image%20%2833%29.png) +4. Click `CLOSE`. Station Extension should prompt you to sign the transaction. Confirm the details presented and input your password to sign. -## Deposit / Withdrawal +## Collateral Deposit / Withdrawal -Users are warned when their CDP is close to liquidation. Minted positions become vulnerable to liquidation when the collateral ratio falls below the `min_collateral_ratio`. Vice versa, minted positions can be over-collateralized when the value of collateral to minted assets increase by a large margin. To avoid liquidation or over-collateralization, user can deposit or withdraw locked collateral from the CDP. +Users are warned when their CDP is close to liquidation. Minted positions become vulnerable to liquidation when the collateral ratio falls below the `min_collateral_ratio`. Vice versa, minted positions can be over-collateralized when the value of collateral to minted assets increases by a large margin. To avoid liquidation or over-collateralization, the user can deposit or withdraw locked collateral from the CDP. 1. Navigate to [**My** **Page**](https://terra.mirror.finance/my)\*\*\*\* -2. In the Mint section, press the "`...`"under actions +2. In the **Borrowings** section, press the "`Manage`"under actions -![](../../.gitbook/assets/image%20%2828%29.png) +![](../../.gitbook/assets/image%20%28145%29.png) 3. Select "`Deposit` / `Withdraw`" -![](../../.gitbook/assets/image%20%2859%29.png) +![](../../.gitbook/assets/image%20%28151%29.png) 4. Enter either amount to deposit/withdraw or collateral ratio. -![](../../.gitbook/assets/image%20%2856%29.png) +![](../../.gitbook/assets/image%20%28143%29.png) + +5. Click the activated button to confirm. Station Extension should prompt you to sign the transaction. Confirm the details presented and input your password to sign. -5. Click action button to confirm. Station Extension should prompt you to sign the transaction. Confirm the details presented and input your password to sign. +6. All done! -![](../../.gitbook/assets/image%20%2860%29.png) +![](../../.gitbook/assets/image%20%28216%29.png) diff --git a/user-guide/getting-started/pool.md b/user-guide/getting-started/pool.md index 084cd60..4d13f87 100644 --- a/user-guide/getting-started/pool.md +++ b/user-guide/getting-started/pool.md @@ -1,44 +1,132 @@ -# Pool +# Farm -The **Pool** page displays operations related to liquidity provision for mAsset and MIR markets. In order to provide liquidity for Mirror assets, you need to supply equal value of the asset and UST. After depositing your assets into the pool, you receive [LP tokens](../../protocol/lp-token.md) which will allow you to reclaim your share of the pool. For more information about Terraswap pools, [click here](../../protocol/terraswap.md). +The **Farm** page displays operations related to liquidity provision, short position creation and earning [LP and sLP token](../../protocol/staking-tokens-lp-and-slp.md) staking rewards. + +In order to create a short position, you need to lock collateral assets to Mirror Protocol, and mint new mAssets. Unlike Borrow positions, newly minted assets are immediately sold at Terraswap price for UST. UST returned for shorting mAssets will be locked for a defined `lock_period`. To close your short position, you must first hold shorted amount of mAssets. These mAssets will be burned to return your locked collateral. + +## Farm Main + +![](../../.gitbook/assets/image%20%28187%29.png) + +The main page of **Farm** provides a list of available staking pools and information corresponding to each pool. + +### **Ticker** + +Name and symbol of the mAsset associated with the staking pool + +### **Long** + +Link to LP Staking \(Long Farm\) page where users can provide liquidity for this asset and start earning MIR reward. The annual percentage rate for Long is calculated by, + +$$\text{Long APR=}\text{(Annual MIR Long Reward} \times \text{MIR Price)}/\text{(Liquidity Value)}$$ + +where $$\text{Annual MIR Long Reward}$$ is the amount distributed to the corresponding mAsset's long staking pool per year, $$\text{MIR Price}$$ is the Terraswap price of MIR token denominated in UST and $$\text{Liquidity Value}$$ is the UST value of total liquidity provided in this mAsset-UST liquidity pool. + +### **Short** + +Link to short position creation \(Short Farm\) page where users can create a short CDP and start earning MIR reward. The annual percentage rate for Short is calculated by, + +$$\text{Short APR = (Annual MIR Short Reward}\times\text{MIR Price)}/\text{(Shorted Token Amount}\times\text{Price)}$$ + +where $$\text{Annual MIR Short Reward}$$ is the amount distributed to the corresponding mAsset's short staking pool per year, $$\text{MIR Price}$$ is the Terraswap Price of MIR token denominated in UST, $$\text{Short Token Amount}$$ is the number of mAssets sold from all short position creation, and $$\text{Price}$$ is the Terraswap price of this mAsset token denominated in UST. + +### **Terraswap Price** + +Current Terraswap pool ratio of the corresponding asset. + +### **Premium** + +Difference ratio between Terraswap and Oracle price of the associated mAsset. The premium is positively correlated with Short reward. Read more about Short reward [here](../../protocol/staking-tokens-lp-and-slp.md#staking-rewards). + +## Long Farm \(LP\) + +In order to provide liquidity for Mirror assets, you need to supply an equal value of the asset and UST. Minted LP tokens will be immediately staked to start earning MIR rewards. By unstaking LP tokens, your liquidity provided will be reclaimable from the Terraswap pool. For more information about Terraswap pools, [click here](../../protocol/terraswap.md). {% hint style="info" %} The Pool interface is directly connected to [Terraswap](https://terraswap.io/). {% endhint %} -## Provide Liquidity +### Stake LP + +1. Navigate to the **Farm** page and select **Long Farm** for the asset to provide liquidity for. + +![](../../.gitbook/assets/image%20%28166%29.png) -1. Navigate to the [**Pool**](https://terra.mirror.finance/pool) page. +2. Enter the amount of selected asset. The App will calculate the amount of UST you will need to deposit as well. -![](../../.gitbook/assets/image%20%2847%29.png) +![](../../.gitbook/assets/image%20%28200%29.png) -2. Select asset for which to provide liquidity and enter amount. +3. Press **`LONG`**. Station Extension should prompt you to sign the transaction. Confirm the details presented and input your password to sign. -![](../../.gitbook/assets/image%20%2857%29.png) +4. The app will automatically stake the LP tokens minted from liquidity provision. + +![](../../.gitbook/assets/image%20%28142%29.png) + +### Unstake LP + +1. Navigate to **My Page** and select `Unstake` by the **Farming** position to unstake from. + +![](../../.gitbook/assets/image%20%28146%29.png) + +2. Enter the amount of LP to unstake and click `Unstake` You may click on your available balance to enter the `MAX` amount. The app will automatically calculate the expected returned amount from this transaction. + +![](../../.gitbook/assets/image%20%28133%29.png) + +3. Press **`Unstake`**. Station Extension will prompt you to sign the transaction. Confirm details presented and enter password to sign. + +## Short Farm + +In order to create a short position, you need to lock collateral assets to Mirror Protocol, and mint new mAssets. Unlike a regular borrow position, newly minted assets are immediately sold at Terraswap price for UST. UST returned for shorting mAssets will be locked for a defined `lock_period`. + +### Stake sLP + +1 . Navigate to **Farm** page, and select **Short Farm** for the asset to create a short position for. + +![](../../.gitbook/assets/image%20%28140%29.png) + +2. Select an asset to provide as collateral and enter the amount. + +![](../../.gitbook/assets/image%20%28161%29.png) + +3. Set the collateral ratio. The app will automatically calculate the expected short amount. + +![](../../.gitbook/assets/image%20%28209%29.png) + +4. Press **`Short`**. Station Extension should prompt you to sign the transaction. Confirm the details presented and input your password to sign. + +5. All done! The app will automatically stake the sLP minted from this transaction. + +![](../../.gitbook/assets/image%20%28180%29.png) + +### Unstake sLP + +{% hint style="warning" %} +To close your short position, you must first hold the shorted amount of mAssets. These mAssets will be burned to return your locked collateral. +{% endhint %} -The App will calculate the amount of UST you will need to deposit as well. +1 . Navigate to **My Page**, and click on `Manage` button on **Borrowing** by the short position to close. -![](../../.gitbook/assets/image%20%2817%29.png) +![](../../.gitbook/assets/image%20%28136%29.png) -3. Press **`Provide`**. Station Extension should prompt you to sign the transaction. Confirm the details presented and input your password to sign. +2. Check the simulated values before executing the transaction. -![](../../.gitbook/assets/image%20%2862%29.png) +![](../../.gitbook/assets/image%20%28184%29.png) -## Withdraw Liquidity +3. Press **`Close`**. Station Extension should prompt you to sign the transaction. Confirm the details presented and input your password to sign. -1. Navigate to the [**Pool**](https://terra.mirror.finance/pool#withdraw) page and select **Withdraw** +### Claiming Locked UST -![](../../.gitbook/assets/image%20%2853%29.png) +After a short position creation, UST from mAssets sold against the Terraswap pool is locked for a defined period called [Lock Period](../../protocol/staking-tokens-lp-and-slp.md#lock-period). When `lock_period` \(initially 15 days\) is over, users may claim their unlocked UST throug the steps below: -2. Select type of LP token to burn and enter amount. +1 . Navigate to **My Page** and go to **Farming** section -![](../../.gitbook/assets/image%20%2865%29.png) +![](../../.gitbook/assets/image%20%28197%29.png) -3. You will be shown the amount of assets reclaimed by burning LP tokens. +2. Below **Short Farming** section, a list of locked UST per each short position is displayed. Click `Claim UST` to retrieve unlocked UST -![](../../.gitbook/assets/image%20%2829%29.png) +![](../../.gitbook/assets/image%20%28201%29.png) -4. Press **`Withdraw`**. Station Extension should prompt you to sign the transaction. Confirm the details presented and input your password to sign. +3. Check the amount to be retreived and press `Claim` -![](../../.gitbook/assets/image%20%2837%29.png) +![](../../.gitbook/assets/image%20%28157%29.png) diff --git a/user-guide/getting-started/sending-tokens.md b/user-guide/getting-started/sending-tokens.md index cec8858..924c8c9 100644 --- a/user-guide/getting-started/sending-tokens.md +++ b/user-guide/getting-started/sending-tokens.md @@ -1,33 +1,30 @@ # Sending Tokens -Users can send ****MIR, mAsset and UST tokens to a different wallet. Tokens can be transferred between Terra blockchain wallets and also to Ethereum or Binance Smart Chain \(BSC\) wallets using a custom bridge which enables cross-chain transfers. +Users can send ****MIR, mAsset and UST tokens to a different wallet. Tokens can be transferred between Terra blockchain wallets and also to Ethereum or Binance Smart Chain \(BSC\) wallets using a custom bridge that enables cross-chain transfers. ## Send {% hint style="danger" %} -$1 or 0.1% fee \(which ever is greater\) from the transfer amount is charge on cross-chain transfer using the Shuttle bridge. +$1 or 0.1% fee \(whichever is greater\) from the transfer amount is charge on cross-chain transfer using the Shuttle bridge. **A transaction with amount smaller than $1 value will be ignored.** {% endhint %} -1. User can navigate to **Send** page by +1. User can navigate to **Send** page by selecting `Send` from Total Value card on **My Page** -* Selecting `Send` from the action button provided by the Holdings list on [**My Page**](https://terra.mirror.finance/my)\*\*\*\* - -![](../../.gitbook/assets/image%20%2886%29.png) - -* Selecting `Send` from the wallet pop-up which appears by clicking the wallet information at the top-right corner of the page - -![](../../.gitbook/assets/image%20%2891%29.png) +![](../../.gitbook/assets/image%20%28195%29.png) 2. Choose a network to send your tokens to. Currently, supported networks are Terra, Ethereum and Binance Smart Chain. -![](../../.gitbook/assets/image%20%28110%29.png) +{% hint style="danger" %} +Token transfers between chains other than Terra does support "Memo" input. +**DO NOT** send your tokens to central exchanges that require a memo, or your tokens may be lost forever. +{% endhint %} + +![](../../.gitbook/assets/image%20%28162%29.png) 3. Select the type of token to send by selecting the dropdown list. Then, enter the amount to send. -![](../../.gitbook/assets/image%20%28106%29.png) +![](../../.gitbook/assets/image%20%28183%29.png) 4. Once all inputs entered correctly, click the button to proceed. Station Extension should prompt you to sign the transaction. Confirm the details presented and input your password to sign. -![](../../.gitbook/assets/image%20%2887%29.png) - diff --git a/user-guide/getting-started/trade.md b/user-guide/getting-started/trade.md index 60b807a..8e67136 100644 --- a/user-guide/getting-started/trade.md +++ b/user-guide/getting-started/trade.md @@ -1,70 +1,55 @@ # Trade -The **Trade** page provides an interface for buying and selling mAsset / MIR tokens against UST. Trades are made against the asset's Terraswap pool and are priced algorithmically by its [automated market making algorithm](../../protocol/terraswap.md#pricing). +The **Market** page provides an interface for trading and borrowing of mAsset tokens. **Trades** are made against the asset's Terraswap pool and priced algorithmically by its [automated market-making algorithm](../../protocol/terraswap.md#pricing). + +## Trade {% hint style="info" %} The Trade interface is directly connected to [Terraswap](../../protocol/terraswap.md). {% endhint %} -## Buy/Sell - -1 . Navigate to the [Trade](https://terra.mirror.finance/trade) page. Select whether to **Buy** or **Sell**. - -![](../../.gitbook/assets/image%20%2813%29.png) +1. Navigate to the **Market** page. Select or search for an asset to trade. -2. Select asset to buy or sell. +![](../../.gitbook/assets/image%20%28208%29.png) -![](../../.gitbook/assets/image%20%2811%29.png) +2. At the top of the page, select one of **Buy or Sell.** -3. Enter amount to buy or sell. Then, click the button below to confirm. +![](../../.gitbook/assets/image%20%28188%29.png) -![](../../.gitbook/assets/image%20%287%29.png) +3. Enter the amount to buy or sell, and check your slippage tolerance and simulated values. If everything is okay, click **Buy** or **Sell.** -{% hint style="warning" %} -The amount shown on the page is an estimate based on the observed pool ratio at time of order. You may actually receive a different amount of tokens due to changes in pool ratio between signing and broadcasting the transaction. +{% hint style="danger" %} +**Slippage tolerance** is the maximum deviation from the Expected Price. Transaction will be reverted if the effective price is different from the expected price by more than slippage tolerance. {% endhint %} -4. Station Extension should prompt you to sign the transaction. Confirm the details presented and input your password to sign. - -![](../../.gitbook/assets/image%20%289%29.png) - -5. All done! +![](../../.gitbook/assets/image%20%28212%29.png) -![](../../.gitbook/assets/image%20%2814%29.png) - -**Special cases:** - -Trading transactions may not complete transaction will not be completed under following circumstances: - -* If the price changes by more than 1% compared to estimated, the protocol will be prevent the transaction in order to protect the user from executing at an unexpected price. -* If the order is exceeds balance of pool, the transaction will fail. +4. Station Extension should prompt you to sign the transaction. Confirm the details presented and input your password to sign. ## Limit Order Limit Order enables users to buy or sell an asset when the price reaches the Bid or Ask price. When user's order is submitted, user's offered mAsset or UST will be locked until the order is executed at Bid/Ask Price or canceled by the user. -1. Navigate to Trade \(**Buy** or **Sell**\) ****page and turn on Limit Order. +1. On **Buy** or **Sell** page and click on Limit Order toggle. -![](../../.gitbook/assets/image%20%28112%29.png) +![](../../.gitbook/assets/image%20%28210%29.png) 2. Select an asset to buy or sell. -![](../../.gitbook/assets/image%20%28113%29.png) +![](../../.gitbook/assets/image%20%28185%29.png) 3. When entering the below information, `Order Value` will be automatically calculated: * **Bid/Ask Price:** The desired price of an mAsset decided by the user. When the Terraswap price of the asset exceeds the Bid/Ask Price by slippage and transaction fee amount, user's order can be executed. -* **Order Amount:** Quantity of the mAsset to buy/sell at bid/ask price. +* **Order Amount:** Quantity of the mAsset to trade at bid/ask price. -![](../../.gitbook/assets/image%20%28117%29.png) +![](../../.gitbook/assets/image%20%28191%29.png) 4. Station Extension should prompt you to sign the transaction. Confirm the details presented and input your password to sign. -![](../../.gitbook/assets/image%20%28114%29.png) - **To cancel Limit Order:** Limit Order is visible on **My Page**. Users can select Cancel from Actions column to remove the submitted Limit Order. -_Please note that your Limit Order can be executed when Terraswap price of the mAsset exceeds the Limit Price due to slippage cause by size of your transaction against the liquidity pool._ +_Please note that your Limit Order can be executed when Terraswap price of the mAsset **exceeds** the Limit Price due to slippage cause by size of your transaction against the liquidity pool._ diff --git a/user-guide/meth-dual-yield/staking_guide.md b/user-guide/meth-dual-yield/staking_guide.md index e8129ca..b3a069b 100644 --- a/user-guide/meth-dual-yield/staking_guide.md +++ b/user-guide/meth-dual-yield/staking_guide.md @@ -2,7 +2,7 @@ {% hint style="info" %} This section covers staking LP tokens on [mETH](https://eth.mirror.finance). -Staking guide for Mirror Web App is available [here](../getting-started/stake.md). +Staking guide for Mirror Web App is available [here](). {% endhint %} Users can stake mAsset-UST LP or MIR-UST LP tokens to earn MIR reward. diff --git a/whats-new-for-mirror-v2.md b/whats-new-for-mirror-v2.md new file mode 100644 index 0000000..05b70f4 --- /dev/null +++ b/whats-new-for-mirror-v2.md @@ -0,0 +1,34 @@ +# What's new for Mirror v2? + +## What’s new for Mirror v2? + +_The below changes are based on_ [_Mirror Forum post_](https://forum.mirror.finance/t/mirror-v2-updates/1077)_._ + +Coming into Mirror Protocol v2, there are new feature additions which supplement existing mechanisms from v1 so that all classes of users are sufficiently incentivized for their given contributions within the protocol. + +### **Governance participation incentives** + +Governance plays a crucial role in the decision-making and success of the Mirror Protocol, but users were not sufficiently incentivized to actively participate. As a result, the quorums were often not reached as users were disincentivized by the fact that their staked MIR tokens were locked until the end of the poll. This was further exacerbated by the fact that MIR deposits were mandatory to create new polls, so poll creators had a relatively high chance to lose their MIR due to lack of poll participation. + +In Mirror Protocol v2, active voters will be eligible for additional voting rewards in addition to existing governance staking rewards. An `ABSTAIN` vote option is also added for users who want to participate actively in governance but feel that they do not adequately understand the proposal. In addition, a snapshot of the quorum will be saved once it reaches a `Snapshot Period` to ensure that additional MIR staked in the governance contract does not affect the minimum amount of MIR needed to reach quorum. + +These changes will drive governance participation upwards by reducing risks related to poll creators’ deposits and incentivizing active participation. + +### **New Collaterals** + +A highly requested feature addition by the community was to add MIR to the list of accepted collaterals for mint positions. + +Including MIR, [new collateral types](protocol/mirrored-assets-massets.md#collateral) from Terra ecosystem have been added in Mirror v2. All collaterals will be given a new governance-decided parameter called the `multiplier` which is multiplied to the `min_collateral_ratio` of minted mAsset. Stable assets such as UST or aUST will have `multiplier`=1, and volatile collaterals including LUNA, MIR and ANC will be initially set to 1.3333334. + +### **Short Incentives** + +One of the largest issues in Mirror Protocol v1 was the persisting price premium between the Terraswap and Oracle price. To reduce price premiums, a user would have to mint an asset and then sell it against Terraswap pools. However, there was no incentive for a user to short an asset since rewards from providing liquidity with bought assets were higher. In addition, minting an asset was much less capital efficient than simply buying the mAsset from Terraswap, even with the price premiums. + +Mirror v2 presents a new non-tradable token called [sLP tokens](protocol/staking-tokens-lp-and-slp.md#slp-tokens-short-tokens), which is minted from creating a short position. sLP tokens are also stakable, and generates a reward that is dynamically increasing or decreasing based on the current price premium between Terraswap and Oracle price. + +### **Pre-IPO Assets** + +Assets scheduled to undergo an IPO can be whitelisted and traded on Mirror v2. Any user can specify the details of the underlying asset via governance poll creation. If the poll passes, these assets will be minted \(during a fixed time window\) or traded like any other mAssets before the IPO. Once the IPO happens in the underlying market, [Mirror Oracle](contracts/oracle.md) will begin reporting prices from the market, and the asset will have the same features as any other mAsset. + +**Security Audit** for the underlying Mirror v2 Contracts is done by **Cryptonics** \(TBD\). +