Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature/fix mint lpt #459

Merged
merged 41 commits into from
Apr 4, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
41 commits
Select commit Hold shift + click to select a range
87b43fe
add validation and change the way to take fee
taiki1frsh Mar 24, 2023
4acb785
modify proto
taiki1frsh Mar 24, 2023
bf9abae
add unit test for MintLiquidityProviderToken
taiki1frsh Mar 24, 2023
dcb1b7f
Merge branch 'feature/open-position-validation' into feature/fix-mint…
taiki1frsh Mar 27, 2023
9c77e33
modify arg type
taiki1frsh Mar 27, 2023
f6fa1d3
Merge pull request #444 from UnUniFi/feature/open-position-validation
taiki1frsh Mar 27, 2023
5e97a16
Merge branch 'newDevelop' into feature/limit-levarage
taiki1frsh Mar 28, 2023
9928943
modify fn to support merged branch
taiki1frsh Mar 28, 2023
cf05a8b
Merge pull request #453 from UnUniFi/feature/limit-levarage
taiki1frsh Mar 28, 2023
4990b1b
Merge branch 'feature/open-position-validation' into feature/fix-mint…
taiki1frsh Mar 27, 2023
bf1d9a1
remove unused
taiki1frsh Mar 28, 2023
55457f3
feat: Generating proto and swagger at the same time
mkXultra Apr 3, 2023
6d42bf1
feat: update query for new nftmarket UI
mkXultra Apr 3, 2023
60fdee0
feat: update query for new nftmarket UI
mkXultra Apr 3, 2023
f0d45ed
modify: refactor code
mkXultra Apr 3, 2023
06324c5
moodify: fix error handling
mkXultra Mar 30, 2023
c4dbda5
Merge branch 'newDevelop' into feature/limit-levarage
taiki1frsh Mar 28, 2023
7106398
modify: refactor
mkXultra Apr 3, 2023
64c8045
modify: refactor code
mkXultra Apr 3, 2023
1e4c119
Merge pull request #471 from UnUniFi/hotfix/issue_470
mkXultra Mar 30, 2023
db87cdd
Merge pull request #453 from UnUniFi/feature/limit-levarage
taiki1frsh Mar 28, 2023
63b9bc0
modify: refactor
mkXultra Apr 3, 2023
ab52846
Merge pull request #473 from UnUniFi/feature/refactor_nftmarket
mkXultra Apr 3, 2023
673a212
chore: derivatives rename
kimurayu45z Mar 28, 2023
9b3c075
Merge pull request #474 from UnUniFi/feature/modify_nftmarket_query
mkXultra Apr 3, 2023
cd8322e
Merge branch 'newDevelop' into feature/limit-levarage
taiki1frsh Mar 28, 2023
a822c82
Merge pull request #464 from UnUniFi/derivatives-rename
mkXultra Apr 4, 2023
e26de09
Merge pull request #453 from UnUniFi/feature/limit-levarage
taiki1frsh Mar 28, 2023
b1f3618
Merge branch 'feature/open-position-validation' into feature/fix-mint…
taiki1frsh Mar 27, 2023
a8b0ac7
Merge branch 'newDevelop' into feature/limit-levarage
taiki1frsh Mar 28, 2023
8aedff9
Merge pull request #453 from UnUniFi/feature/limit-levarage
taiki1frsh Mar 28, 2023
9f76a33
Merge branch 'newDevelop' into feature/limit-levarage
taiki1frsh Mar 28, 2023
643b569
Merge pull request #453 from UnUniFi/feature/limit-levarage
taiki1frsh Mar 28, 2023
d265854
Merge branch 'newDevelop' into feature/limit-levarage
taiki1frsh Mar 28, 2023
87a3fcc
Merge branch 'feature/open-position-validation' into feature/fix-mint…
taiki1frsh Mar 27, 2023
113f280
Merge branch 'newDevelop' into feature/limit-levarage
taiki1frsh Mar 28, 2023
9eaf448
Merge pull request #453 from UnUniFi/feature/limit-levarage
taiki1frsh Mar 28, 2023
ca1109d
Merge pull request #453 from UnUniFi/feature/limit-levarage
taiki1frsh Mar 28, 2023
6dd2d0c
Merge branch 'feature/open-position-validation' into feature/fix-mint…
taiki1frsh Mar 27, 2023
6b84460
Merge branch 'newDevelop' into feature/fix-mint-lpt
taiki1frsh Apr 4, 2023
0d38260
fix EstimateDLPTokenAmount q and regarding fn
taiki1frsh Apr 4, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions docs/core/proto-docs.md
Original file line number Diff line number Diff line change
Expand Up @@ -2006,8 +2006,8 @@ GenesisState defines the derivatives module's genesis state.

| Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- |
| `amount` | [cosmos.base.v1beta1.Coin](#cosmos.base.v1beta1.Coin) | | |
| `fee` | [cosmos.base.v1beta1.Coin](#cosmos.base.v1beta1.Coin) | | |
| `estimated_dlp_amount` | [cosmos.base.v1beta1.Coin](#cosmos.base.v1beta1.Coin) | | |
| `deposit_fee` | [cosmos.base.v1beta1.Coin](#cosmos.base.v1beta1.Coin) | | |



Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Based on the code patch you provided, it seems that a field called fee of type cosmos.base.v1beta1.Coin has been removed from the GenesisState struct.

Without more context or information about how this struct is being used in your codebase, it is difficult to determine if there are any bug risks or potential improvements. However, if the removal of the fee field was intended and does not impact any other parts of your codebase, then this change should be safe to commit.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

with a quick code review

Firstly, it appears that the fields "amount" and "fee" have been changed to "estimated_dlp_amount" and "deposit_fee", respectively. This is a good change as it provides more clarity on the purpose of the fields. Also, it is important to check that the types of the fields have not changed and are still of type cosmos.base.v1beta1.Coin. It is also worth noting that the labels and descriptions of the fields have not changed, which is a good thing, as they provide useful information about the fields.

Overall, this patch looks good, however, it is important to test it thoroughly to make sure there are no unexpected bugs or errors. Additionally, if possible, it might be a good idea to add more documentation about these changes for future reference.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This code patch changes two field names in the GenesisState struct of the derivatives module: amount is renamed to estimated_dlp_amount and fee is renamed to deposit_fee. The types and labels of both fields remain unchanged.

As this is only a naming change, there should not be any bug risks associated with this code patch. However, it is worth noting that depending on how extensively other parts of the project rely on these field names, there may be some necessary updates to ensure compatibility.

Regarding improvements, without more context on the purpose and usage of these fields, it's difficult to provide specific suggestions. Generally speaking, clear and descriptive field names are helpful for code readability and maintainability, so if these new names accurately reflect the meaning of the data being represented, they could be considered an improvement.

Expand Down
6 changes: 3 additions & 3 deletions proto/derivatives/query.proto
Original file line number Diff line number Diff line change
Expand Up @@ -301,12 +301,12 @@ message QueryEstimateDLPTokenAmountRequest {
}

message QueryEstimateDLPTokenAmountResponse {
cosmos.base.v1beta1.Coin amount = 1 [
cosmos.base.v1beta1.Coin estimated_dlp_amount = 1 [
(gogoproto.moretags) = "yaml:\"amount\"",
(gogoproto.nullable) = false
];
cosmos.base.v1beta1.Coin fee = 2 [
(gogoproto.moretags) = "yaml:\"fee\"",
cosmos.base.v1beta1.Coin deposit_fee = 2 [
(gogoproto.moretags) = "yaml:\"deposit_fee\"",
(gogoproto.nullable) = false
];
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review:

  1. The code patch renames the field amount to estimated_dlp_amount and the field fee to deposit_fee, which makes the code more descriptive and easier to understand.

  2. In the code patch, the gogoproto.nullable is set to false, which implies that the fields are required and cannot be set to null.

  3. The code patch also adds a yaml tag to the fields, which may be useful when mapping the fields to YAML configuration files.

Overall, the code patch looks good and there don't appear to be any bug risks. However, it would be helpful to add some comments to explain why the changes were made.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The code patch seems to be a protobuf definition for QueryEstimateDLPTokenAmountRequest and QueryEstimateDLPTokenAmountResponse.

Regarding the changes, it looks like the field amount in the QueryEstimateDLPTokenAmountResponse message has been renamed to estimated_dlp_amount, and a new field deposit_fee has been added. This change seems reasonable based on the context.

As for potential improvements, it's tough to say without more details about the use case or wider codebase. Generally speaking, it would be helpful to ensure that the variable names are clear and descriptive, and that the documentation is accurate and up-to-date. It may also be beneficial to review any relevant API or client requirements to ensure that the changes don't introduce any compatibility issues.

Expand Down
17 changes: 12 additions & 5 deletions x/derivatives/keeper/grpc_query.go
Original file line number Diff line number Diff line change
Expand Up @@ -333,23 +333,30 @@ func (k Keeper) EstimateDLPTokenAmount(c context.Context, req *types.QueryEstima
return nil, status.Error(codes.InvalidArgument, "invalid request")
}

validCoin := sdk.Coin{
deposit := sdk.Coin{
Denom: req.MintDenom,
Amount: validAmount,
}
if validCoin.Validate() != nil {
if deposit.Validate() != nil {
return nil, status.Error(codes.InvalidArgument, "invalid request")
}

ctx := sdk.UnwrapSDKContext(c)
mintAmount, mintFee, err := k.DetermineMintingLPTokenAmount(ctx, validCoin)

depositFee, err := k.CalcDepositingFee(ctx, deposit, k.GetLPTokenBaseMintFee(ctx))
if err != nil {
return nil, status.Error(codes.InvalidArgument, err.Error())
}

depositFeeDeducted := deposit.Sub(depositFee)
mintAmount, err := k.DetermineMintingLPTokenAmount(ctx, depositFeeDeducted)
if err != nil {
return nil, status.Error(codes.InvalidArgument, err.Error())
}

return &types.QueryEstimateDLPTokenAmountResponse{
Amount: mintAmount,
Fee: mintFee,
EstimatedDlpAmount: mintAmount,
DepositFee: depositFee,
}, nil
}

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This code patch removes the mintFee variable and its assignment from the EstimateDLPTokenAmount() function. It means that the function does not return the estimated minting fees anymore. Make sure that this change is intended and will not break any other parts of the system that rely on the mintFee value.

Other than that, there are no obvious bug risks in this code patch. However, it's always a good idea to thoroughly test any changes before deploying them to production. As for improvement suggestions, I cannot provide any without seeing the larger context of the codebase and the desired outcomes.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

with the Code review

  1. In line 8, the variable "deposit" should be used instead of "validCoin" to make the code more readable and understandable.
  2. Starting on line 11, a new variable should be created to store the deposit fee which can then be used in the next few lines instead of using the deposit amount directly.
  3. Line 14 should use the new depositFee variable instead of calling the CalcDepositingFee method again.
  4. Line 17 should use the new depositFeeDeducted variable instead of the deposit variable.
  5. Line 19 should use the EstimatedDlpAmount instead of Amount to make the code more readable.
  6. The Fee field should also be updated to DepositFee for consistency.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Based on the code patch provided, here are my observations:

  • This code block is an implementation of the EstimateDLPTokenAmount function in Go Programming Language.
  • The function takes a context c and a request type QueryEstimateDLPTokenAmountRequest as input parameters and returns an estimate of the DLP Token amount along with a deposit fee.
  • It starts by validating the inputs to ensure that they are valid.
  • A deposit variable is created, which is an instance of the sdk.Coin struct, and it contains the values passed in the request.
  • A deposit fee is then calculated using the CalcDepositingFee method.
  • After calculating the deposit fee, it is deducted from the deposit, and the DetermineMintingLPTokenAmount method is called to calculate the minting amount of LPTokens.
  • Finally, the function returns the estimated minting amount of DLP tokens along with the deposit fee.

Here are some suggestions for improvement:

  • Ensure that the function handles errors correctly and provides appropriate error messages to the user.
  • Check if the fees being charged are reasonable, to avoid overcharging or undercharging users.
  • Consider adding unit tests or integration tests to ensure that the code behaves as expected in different scenarios.

Expand Down
87 changes: 44 additions & 43 deletions x/derivatives/keeper/lpt.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package keeper

import (
"fmt"

sdk "github.com/cosmos/cosmos-sdk/types"

"github.com/UnUniFi/chain/x/derivatives/types"
Expand Down Expand Up @@ -48,24 +50,13 @@ func (k Keeper) GetLPTokenPrice(ctx sdk.Context) sdk.Dec {

// amount: amount of asset that will go to pool
// return1: amount of LP token that value is equal to the asset that will go to pool
// return2: mint fee amount of LP token (fee included in return1)
func (k Keeper) DetermineMintingLPTokenAmount(ctx sdk.Context, amount sdk.Coin) (sdk.Coin, sdk.Coin, error) {
func (k Keeper) DetermineMintingLPTokenAmount(ctx sdk.Context, amount sdk.Coin) (sdk.Coin, error) {
currentSupply := k.bankKeeper.GetSupply(ctx, types.LiquidityProviderTokenDenom)

// assetPrice is the price of the asset in metrics ticker (USD in default)
assetPrice, err := k.GetAssetPrice(ctx, amount.Denom)
if err != nil {
return sdk.Coin{}, sdk.Coin{}, err
}
// actualAmount means the amount of the asset that is in the pool
actualAmount := k.GetAssetBalance(ctx, amount.Denom)

// for asset "i",
// targetAmount[i] = targetWeight[i] * poolMarketCap / price[i]
// targetWeight is determined in params of pool
targetAmount, err := k.GetAssetTargetAmount(ctx, amount.Denom)
if err != nil {
return sdk.Coin{}, sdk.Coin{}, err
return sdk.Coin{}, err
}

// assetMc is the market cap of the asset that will go to the pool, in metrics ticker (USD in default)
Expand All @@ -77,22 +68,12 @@ func (k Keeper) DetermineMintingLPTokenAmount(ctx sdk.Context, amount sdk.Coin)

lptPrice := k.GetLPTokenPrice(ctx)
if lptPrice.IsZero() {
return sdk.Coin{}, sdk.Coin{}, types.ErrZeroLpTokenPrice
return sdk.Coin{}, types.ErrZeroLpTokenPrice
}

mintAmount := assetMc.Quo(lptPrice)

// increaseRate = (actualAmount - targetAmount) / targetAmount
increaseRate := sdk.NewDecFromInt(actualAmount.Amount).Sub(sdk.NewDecFromInt(targetAmount.Amount)).Quo(sdk.NewDecFromInt(targetAmount.Amount))
if increaseRate.IsNegative() {
increaseRate = sdk.NewDec(0)
}

// mintFeeRate = baseMintFeeRate * (1 + increaseRate)
mintFeeRate := k.GetLPTokenBaseMintFee(ctx).Mul(increaseRate.Add(sdk.NewDecWithPrec(1, 0)))

// mintFee = mintFeeRate * mintAmount
return sdk.NewCoin(types.LiquidityProviderTokenDenom, mintAmount.TruncateInt()), sdk.NewCoin(types.LiquidityProviderTokenDenom, mintAmount.Mul(mintFeeRate).TruncateInt()), nil
return sdk.NewCoin(types.LiquidityProviderTokenDenom, mintAmount.TruncateInt()), nil
}

// Assume the ticker of LP token is DLP and redeemDenom is XXX, then this emits the rate of DLP/XXX
Expand Down Expand Up @@ -186,59 +167,79 @@ func (k Keeper) DecreaseRedeemDenomAmount(ctx sdk.Context, amount sdk.Coin) erro
// initial_lp_token_price = Σ target_weight_of_ith_asset * price_of_ith_asset
// pool_marketcap = price_of_ith_asset * amount_of_ith_deopsited_asset
// initial_lp_supply = pool_marketcap / initial_lp_token_price
func (k Keeper) InitialLiquidityProviderTokenSupply(ctx sdk.Context, assetPrice *pftypes.CurrentPrice, assetMarketCap sdk.Dec, depositDenom string) (sdk.Coin, sdk.Coin, error) {
func (k Keeper) InitialLiquidityProviderTokenSupply(ctx sdk.Context, assetPrice *pftypes.CurrentPrice, assetMarketCap sdk.Dec, depositDenom string) (sdk.Coin, error) {
assetInfo := k.GetPoolAssetByDenom(ctx, depositDenom)
initialLPTokenPrice := assetPrice.Price.Mul(assetInfo.TargetWeight)
initialLPTokenSupply := assetMarketCap.Quo(initialLPTokenPrice)

return sdk.NewCoin(types.LiquidityProviderTokenDenom, initialLPTokenSupply.TruncateInt()),
sdk.NewCoin(types.LiquidityProviderTokenDenom, sdk.ZeroInt()),
nil
}

func (k Keeper) MintLiquidityProviderToken(ctx sdk.Context, msg *types.MsgDepositToPool) error {
depositor := msg.Sender.AccAddress()

// TODO: check if deposit token is acceptable

err := k.bankKeeper.SendCoinsFromAccountToModule(ctx, depositor, types.ModuleName, sdk.Coins{msg.Amount})
if err != nil {
return err
params := k.GetParams(ctx)
// check if the deposit denom is valid and amount is positive
if !types.IsValidDepositForPool(msg.Amount, params.PoolParams.AcceptedAssets) {
return fmt.Errorf("invalid deposit token: %s", msg.Amount.Denom)
}

mintAmount, mintFee, err := k.DetermineMintingLPTokenAmount(ctx, msg.Amount)
if err != nil {
if err := k.bankKeeper.SendCoinsFromAccountToModule(ctx, depositor, types.ModuleName, sdk.Coins{msg.Amount}); err != nil {
return err
}

err = k.bankKeeper.MintCoins(ctx, types.ModuleName, sdk.Coins{mintAmount})
fee, err := k.CalcDepositingFee(ctx, msg.Amount, params.PoolParams.BaseLptMintFee)
if err != nil {
return err
}

if mintFee.IsPositive() {
// send mint fee to fee pool
err = k.bankKeeper.SendCoinsFromModuleToModule(ctx, types.ModuleName, types.DerivativeFeeCollector, sdk.Coins{mintFee})
if err != nil {
// TODO: integrate into ecosystem-incentive module
// temporarily, send mint fee to fee pool of the derivatives module
if fee.IsPositive() {
if err := k.bankKeeper.SendCoinsFromModuleToModule(ctx, types.ModuleName, types.DerivativeFeeCollector, sdk.Coins{fee}); err != nil {
return err
}
} else {
if fee.IsNegative() {
return fmt.Errorf("negative fee: %s", fee)
}
}

reductedMintAmount, err := mintAmount.SafeSub(mintFee)
deposit, err := msg.Amount.SafeSub(fee)
if err != nil {
return err
}

// send to user
err = k.bankKeeper.SendCoinsFromModuleToAccount(ctx, types.ModuleName, depositor, sdk.Coins{reductedMintAmount})
mintingDLP, err := k.DetermineMintingLPTokenAmount(ctx, deposit)
if err != nil {
return err
}

k.DepositPoolAsset(ctx, depositor, msg.Amount)
if err := k.bankKeeper.MintCoins(ctx, types.ModuleName, sdk.Coins{mintingDLP}); err != nil {
return err
}

// send to user
if err := k.bankKeeper.SendCoinsFromModuleToAccount(ctx, types.ModuleName, depositor, sdk.Coins{mintingDLP}); err != nil {
return err
}

k.DepositPoolAsset(ctx, depositor, deposit)
return nil
}

func (k Keeper) CalcDepositingFee(ctx sdk.Context, depositingAmount sdk.Coin, baseLptMintFee sdk.Dec) (sdk.Coin, error) {
currentBalance := k.GetAssetBalance(ctx, depositingAmount.Denom)
targetBalance, err := k.GetAssetTargetAmount(ctx, depositingAmount.Denom)
if err != nil {
return sdk.Coin{}, err
}
fee := types.CalculateMintFee(currentBalance, targetBalance, depositingAmount, baseLptMintFee)

return fee, nil
}

func (k Keeper) BurnLiquidityProviderToken(ctx sdk.Context, msg *types.MsgWithdrawFromPool) error {
// todo:check validator address,amount,redeem denom
// todo: use CacheCtx
Expand Down
Loading