Skip to content

Commit fc9e591

Browse files
authored
Update cosmwasmpool doc (#7328)
* update doc * fix fence
1 parent 2454624 commit fc9e591

File tree

1 file changed

+92
-33
lines changed

1 file changed

+92
-33
lines changed

x/cosmwasmpool/README.md

Lines changed: 92 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
# CosmWasm Pool
22

3-
43
## Overview
54

65
The CosmWasm Pool Module is an extension for the Osmosis pools, aiming to create a custom module that allows users to create and manage liquidity pools backed by CosmWasm smart contracts. The feature enables developers to build and deploy custom smart contracts that can be integrated with the rest of the pool types on the Osmosis chain.
@@ -10,33 +9,34 @@ The module is built on top of the CosmWasm smart contracting platform, which pro
109
Having pools in CosmWasm provides several benefits, one of which is avoiding the need for chain upgrades when introducing new functionalities or modifying existing ones related to liquidity pools. This advantage is particularly important in the context of speed of development and iteration.
1110

1211
An example of a CosmWasm pool type:
12+
1313
- [transmuter](https://github.com/osmosis-labs/transmuter)
1414

1515
## Key Components
1616

1717
- **Keeper**: The module's keeper is responsible for managing the state of the CosmWasm pools, including creating and initializing pools,
18-
querying pool data, and executing privileged operations such as swaps using the CosmWasm sudo message.
19-
* `InitializePool`: Initializes a new CosmWasm pool by instantiating a Wasm contract and storing the pool model in the keeper.
20-
* `Swap operations`: Swap operations like `SwapExactAmountIn` and `SwapExactAmountOut` are implemented, allowing users to perform swaps
21-
within the CosmWasm pools.
22-
* `Swap estimation`: Functions like CalcOutAmtGivenIn, and CalcInAmtGivenOut are provided to calculate prices and amounts for swap operations.
23-
* `Pool information`: Functions like `CalculateSpotPrice`, `GetPool`, `GetPoolAssets`, `GetPoolBalances`, `GetPoolTotalShares` allow
24-
for querying the state of the CosmWasm pools.
18+
querying pool data, and executing privileged operations such as swaps using the CosmWasm sudo message.
2519

20+
- `InitializePool`: Initializes a new CosmWasm pool by instantiating a Wasm contract and storing the pool model in the keeper.
21+
- `Swap operations`: Swap operations like `SwapExactAmountIn` and `SwapExactAmountOut` are implemented, allowing users to perform swaps
22+
within the CosmWasm pools.
23+
- `Swap estimation`: Functions like CalcOutAmtGivenIn, and CalcInAmtGivenOut are provided to calculate prices and amounts for swap operations.
24+
- `Pool information`: Functions like `CalculateSpotPrice`, `GetPool`, `GetPoolAssets`, `GetPoolBalances`, `GetPoolTotalShares` allow
25+
for querying the state of the CosmWasm pools.
2626

2727
- **Query and Sudo functions**: The module includes generic functions to query CosmWasm smart contracts and execute sudo messages.
28-
The Query and Sudo functions are used to interact with the smart contracts, while MustQuery and MustSudo variants panic if an error
29-
occurs during the query or sudo call, respectively.
28+
The Query and Sudo functions are used to interact with the smart contracts, while MustQuery and MustSudo variants panic if an error
29+
occurs during the query or sudo call, respectively.
3030

3131
- **`poolmanager.PoolI` Interface**: The CosmWasm Pool Model implements the PoolI interface from the Pool Manager Module to enable
32-
the creation and management of liquidity pools backed by CosmWasm smart contracts. By implementing the PoolI interface, the model
33-
ensures compatibility with the existing Pool Manager Module's structure and functionalities and integrates seamlessly with
34-
other modules such as `x/concentrated-liquidity` and `x/gamm`.
32+
the creation and management of liquidity pools backed by CosmWasm smart contracts. By implementing the PoolI interface, the model
33+
ensures compatibility with the existing Pool Manager Module's structure and functionalities and integrates seamlessly with
34+
other modules such as `x/concentrated-liquidity` and `x/gamm`.
3535

3636
- **`poolmanager.PoolModule` Interface**: To integrate the CosmWasm Pool Module with the existing Pool Manager Module,
37-
the module's keeper has to implement the PoolModule interface from `x/poolmanager` Module. By implementing the PoolModule interface,
38-
the CosmWasm Pool Keeper can register itself as an extension to the existing Pool Manager Module and handle the creation and management
39-
of CosmWasm-backed liquidity pools as well as receive swaps propagated from the `x/poolmanager`.
37+
the module's keeper has to implement the PoolModule interface from `x/poolmanager` Module. By implementing the PoolModule interface,
38+
the CosmWasm Pool Keeper can register itself as an extension to the existing Pool Manager Module and handle the creation and management
39+
of CosmWasm-backed liquidity pools as well as receive swaps propagated from the `x/poolmanager`.
4040

4141
## Creating new CosmWasm Pool
4242

@@ -53,7 +53,6 @@ graph TD;
5353

5454
The CosmWasm contract that is to be instanitiated needs to implement [CosmWasm Pool Contract Interface](#cosmwasm-pool-contract-interface) and store it on chain first. Then new pool can be created by sending `MsgCreateCosmWasmPool`.
5555

56-
5756
`MsgCreateCosmWasmPool` contains `InstantiateMsg`, which is a message that will be passed to the CosmWasm contract when it is instantiated. The structure of the message is defined by the contract developer, and can contain any information that the contract needs to be instantiated. JSON format is used for `InstantiateMsg`.
5857

5958
```mermaid
@@ -78,7 +77,6 @@ sequenceDiagram
7877
x/cosmwasmpool -->> Sender: MsgCreateCosmWasmPoolResponse {PoolId}
7978
```
8079

81-
8280
## Providing / Withdrawing Liquidity
8381

8482
Currently, all existing pool types have their own way of providing liquidity and shares calculation. CosmWasm pool aims to be flexible that regards and let the contract define the way of providing liquidity. So there is no restriction here, and the contract developer can define the way of providing liquidity as they wish, potentially with execute endpoint since `MsgExecuteContract` triggers state mutating endpoint and can also attach funds to it.
@@ -87,7 +85,6 @@ Common interface and later be defined for the contract to implement as spec and/
8785

8886
It's important to note that the _**contract itself hold tokens that are provided by users**_.
8987

90-
9188
## Swap
9289

9390
One of the main reason why CosmWasm pool is implemented as a module + contract rather than a contract only is that it allows us to use the existing pool manager module to handle swap, which means things like swap routing, cross chain swap, and other functionality that depends on existing pool interface works out of the box.
@@ -121,7 +118,6 @@ SwapExactAmountOut {
121118

122119
`SwapExactAmountIn`
123120

124-
125121
```mermaid
126122
graph TD;
127123
Sender((Sender))
@@ -133,7 +129,6 @@ graph TD;
133129
wasm/pool -- 6. send token_out to sender --> x/bank
134130
```
135131

136-
137132
`SwapExactAmountOut`
138133

139134
```mermaid
@@ -142,11 +137,11 @@ graph TD;
142137
Sender -- 1. swap --> x/poolmanager
143138
x/poolmanager -- 2. route msg to --> x/cosmwasmpool
144139
x/cosmwasmpool -- 3. sudo execute contract --> x/wasm
145-
140+
146141
x/cosmwasmpool -- 4. send token_in_max_amount from sender to wasm/pool --> x/bank
147142
x/wasm -- 5. sudo --> wasm/pool
148143
x/cosmwasmpool -- 6. send remaining wasm/pool to sender --> x/bank
149-
144+
150145
wasm/pool -- 7. send token_out to sender --> x/bank
151146
```
152147

@@ -158,6 +153,63 @@ And because sudo message can't attach funds like execute message, chain-side is
158153

159154
And the reason why the sequence is a little bit different for `SwapExactAmountIn` and `SwapExactAmountOut` is that, for `SwapExactAmountIn`, it is known beforehand how much `token_in_amount` to be sent to the contract and let it process, but for `SwapExactAmountOut`, it isn't, so we need to sent `token_in_max_amount` to the contract and let it process, then send the remaining token back to the sender.
160155

156+
To complete the swap, the sudo response needs to `set_data` with calculated amount in JSON so that swap router has the required value to calculate further swap operations.
157+
158+
`SwapExactAmountIn`:
159+
160+
```json
161+
{
162+
"token_out_amount": "<AMOUNT>"
163+
}
164+
```
165+
166+
`SwapExactAmountOut`:
167+
168+
```json
169+
{
170+
"token_in_amount": "<AMOUNT>"
171+
}
172+
```
173+
174+
So your code might look like this:
175+
176+
```rs
177+
#[cw_serde]
178+
pub struct SwapExactAmountInResponseData {
179+
pub token_out_amount: Uint128,
180+
}
181+
182+
#[cw_serde]
183+
pub struct SwapExactAmountOutResponseData {
184+
pub token_in_amount: Uint128,
185+
}
186+
```
187+
188+
```rs
189+
#[entry_point]
190+
pub fn sudo(deps: DepsMut, env: Env, msg: SudoMessage) -> Result<Response, ContractError> {
191+
match msg {
192+
SudoMessage::SwapExactAmountIn { sender, token_in, token_out_denom, token_out_min_amount, swap_fee } => {
193+
let token_out_amount = todo!("calculate token_out_amount");
194+
195+
Response::new()
196+
.set_data(to_json_binary(&SwapExactAmountInResponseData {
197+
token_out_amount
198+
})?)
199+
},
200+
SudoMessage::SwapExactAmountOut { sender, token_in_denom, token_in_max_amount, token_out, swap_fee } => {
201+
let token_in_amount = todo!("calculate token_in_amount");
202+
203+
Response::new()
204+
.set_data(to_json_binary(&SwapExactAmountOutResponseData {
205+
token_in_amount
206+
})?)
207+
},
208+
_ => todo!(),
209+
}
210+
}
211+
```
212+
161213
## Deactivating
162214

163215
On contract's sudo endpoint, `SetActive` can be called to deactivate the pool. This will prevent the pool from being used for swap, and also prevent users from providing liquidity to the pool. Contract needs to check if the pool is active before performing any state mutating operation except `SetActive`.
@@ -177,6 +229,7 @@ The contract interface is defined so that `cosmwasmpool` can delegate `PoolI` an
177229
The following are the messages that the contract needs to implement. (If you have trouble interpreting this, please read [Rust de/serialization](#rust-deserialization))
178230

179231
### Query
232+
180233
```rs
181234
#[cw_serde]
182235
#[derive(QueryResponses)]
@@ -337,9 +390,11 @@ pub enum CreatePoolGauges {
337390
```
338391

339392
---
393+
340394
## Appendix
341395

342396
### TWAP
397+
343398
`x/twap` is not implemented for cosmwasm pools but can be in the future if there is a need.
344399

345400
### Rust de/serialization
@@ -365,7 +420,7 @@ struct SpotPriceResponse {
365420
}
366421
```
367422

368-
[Decimal](https://docs.rs/cosmwasm-std/1.2.3/cosmwasm_std/struct.Decimal.html) and [Uint128](https://docs.rs/cosmwasm-std/1.2.3/cosmwasm_std/struct.Uint128.html) are represented as string in JSON.
423+
[Decimal](https://docs.rs/cosmwasm-std/1.2.3/cosmwasm_std/struct.Decimal.html) and [Uint128](https://docs.rs/cosmwasm-std/1.2.3/cosmwasm_std/struct.Uint128.html) are represented as string in JSON.
369424

370425
[Coin](https://docs.rs/cosmwasm-std/1.2.3/cosmwasm_std/struct.Coin.html) is:
371426

@@ -412,7 +467,8 @@ No address will be able to maliciously upload a new code id and instantiate a po
412467
governance approval.
413468

414469
Inputs
415-
- `uploadByteCode` - `[]byte` - the raw wasm bytecode
470+
471+
- `uploadByteCode` - `[]byte` - the raw wasm bytecode
416472

417473
The created code id is emitted via `TypeEvtUploadedCosmwasmPoolCode` event.
418474

@@ -437,21 +493,23 @@ The reason for having `poolID`s be a slice of ids is to account for the potentia
437493
The proposal fails if more. Note that 20 was chosen arbitrarily to have a constant bound on the number of pools migrated at once.
438494

439495
Inputs
440-
- `poolIDs` - `[]uint64`
441-
- `codeID` - `uint64`
442-
- `uploadByteCode` - `[]byte`
443496

444-
If the code is uploaded via proposal, the resulting code id is emitted via `TypeEvtMigratedCosmwasmPoolCode`.
497+
- `poolIDs` - `[]uint64`
498+
- `codeID` - `uint64`
499+
- `uploadByteCode` - `[]byte`
500+
501+
If the code is uploaded via proposal, the resulting code id is emitted via `TypeEvtMigratedCosmwasmPoolCode`.
445502

446503
##### Analysis of the Parameter Choice
447504

448505
- Pros
449-
* The flexibility is maximized as each pool id can be migrated individually either by uploading a new contract code or migrating to a pre-added one.
450-
* There is still an ability to migrate all pools belonging to a list of code ids. The max number of pools migrated at once is bounded by a constant parameter.
506+
507+
- The flexibility is maximized as each pool id can be migrated individually either by uploading a new contract code or migrating to a pre-added one.
508+
- There is still an ability to migrate all pools belonging to a list of code ids. The max number of pools migrated at once is bounded by a constant parameter.
451509

452510
- Cons
453-
* If there are multiple iterations of the same type, It might become cumbersome to keep track of which pool is on which code id, why one is migrated and the other one is not
454-
* Some conditionality with proposal parameters. For example, if `codeId` is zero, byte code must be empty.
511+
- If there are multiple iterations of the same type, It might become cumbersome to keep track of which pool is on which code id, why one is migrated and the other one is not
512+
- Some conditionality with proposal parameters. For example, if `codeId` is zero, byte code must be empty.
455513

456514
Overall, we concluded that pros outweigh the cons, and this is the best approach out of the other alternatives considered.
457515

@@ -475,6 +533,7 @@ can tweak it by changing the `PoolMigrationLimit` parameter.
475533
## Pool Model
476534

477535
Note: CW Pool has 2 pool models:
536+
478537
- CosmWasmPool which is a proto-generated store model used for serialization into state.
479538
- Pool struct that encapsulates the CosmWasmPool and wasmKeeper for calling the contract.
480539

0 commit comments

Comments
 (0)