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

BE-678 | InGivenOut APIs for Cosmwasm pool #606

Merged
merged 5 commits into from
Jan 30, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
116 changes: 116 additions & 0 deletions domain/mocks/wasm_client.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
package mocks

import (
"context"

wasmtypes "github.com/CosmWasm/wasmd/x/wasm/types"

"google.golang.org/grpc"
)

type WasmClient struct {
ContractInfoFunc func(ctx context.Context, in *wasmtypes.QueryContractInfoRequest, opts ...grpc.CallOption) (*wasmtypes.QueryContractInfoResponse, error)
ContractHistoryFunc func(ctx context.Context, in *wasmtypes.QueryContractHistoryRequest, opts ...grpc.CallOption) (*wasmtypes.QueryContractHistoryResponse, error)
ContractsByCodeFunc func(ctx context.Context, in *wasmtypes.QueryContractsByCodeRequest, opts ...grpc.CallOption) (*wasmtypes.QueryContractsByCodeResponse, error)
AllContractStateFunc func(ctx context.Context, in *wasmtypes.QueryAllContractStateRequest, opts ...grpc.CallOption) (*wasmtypes.QueryAllContractStateResponse, error)
RawContractStateFunc func(ctx context.Context, in *wasmtypes.QueryRawContractStateRequest, opts ...grpc.CallOption) (*wasmtypes.QueryRawContractStateResponse, error)
SmartContractStateFunc func(ctx context.Context, in *wasmtypes.QuerySmartContractStateRequest, opts ...grpc.CallOption) (*wasmtypes.QuerySmartContractStateResponse, error)
CodeFunc func(ctx context.Context, in *wasmtypes.QueryCodeRequest, opts ...grpc.CallOption) (*wasmtypes.QueryCodeResponse, error)
CodesFunc func(ctx context.Context, in *wasmtypes.QueryCodesRequest, opts ...grpc.CallOption) (*wasmtypes.QueryCodesResponse, error)
PinnedCodesFunc func(ctx context.Context, in *wasmtypes.QueryPinnedCodesRequest, opts ...grpc.CallOption) (*wasmtypes.QueryPinnedCodesResponse, error)
ParamsFunc func(ctx context.Context, in *wasmtypes.QueryParamsRequest, opts ...grpc.CallOption) (*wasmtypes.QueryParamsResponse, error)
ContractsByCreatorFunc func(ctx context.Context, in *wasmtypes.QueryContractsByCreatorRequest, opts ...grpc.CallOption) (*wasmtypes.QueryContractsByCreatorResponse, error)
BuildAddressFunc func(ctx context.Context, in *wasmtypes.QueryBuildAddressRequest, opts ...grpc.CallOption) (*wasmtypes.QueryBuildAddressResponse, error)
}

func (m *WasmClient) ContractInfo(ctx context.Context, in *wasmtypes.QueryContractInfoRequest, opts ...grpc.CallOption) (*wasmtypes.QueryContractInfoResponse, error) {
if m.ContractInfoFunc != nil {
return m.ContractInfoFunc(ctx, in, opts...)
}
panic("MockQueryClient.ContractInfo unimplemented")
}

func (m *WasmClient) ContractHistory(ctx context.Context, in *wasmtypes.QueryContractHistoryRequest, opts ...grpc.CallOption) (*wasmtypes.QueryContractHistoryResponse, error) {
if m.ContractHistoryFunc != nil {
return m.ContractHistoryFunc(ctx, in, opts...)
}
panic("MockQueryClient.ContractHistory unimplemented")
}

func (m *WasmClient) ContractsByCode(ctx context.Context, in *wasmtypes.QueryContractsByCodeRequest, opts ...grpc.CallOption) (*wasmtypes.QueryContractsByCodeResponse, error) {
if m.ContractsByCodeFunc != nil {
return m.ContractsByCodeFunc(ctx, in, opts...)
}
panic("MockQueryClient.ContractsByCode unimplemented")
}

func (m *WasmClient) AllContractState(ctx context.Context, in *wasmtypes.QueryAllContractStateRequest, opts ...grpc.CallOption) (*wasmtypes.QueryAllContractStateResponse, error) {
if m.AllContractStateFunc != nil {
return m.AllContractStateFunc(ctx, in, opts...)
}
panic("MockQueryClient.AllContractState unimplemented")
}

func (m *WasmClient) RawContractState(ctx context.Context, in *wasmtypes.QueryRawContractStateRequest, opts ...grpc.CallOption) (*wasmtypes.QueryRawContractStateResponse, error) {
if m.RawContractStateFunc != nil {
return m.RawContractStateFunc(ctx, in, opts...)
}
panic("MockQueryClient.RawContractState unimplemented")
}

func (m *WasmClient) SmartContractState(ctx context.Context, in *wasmtypes.QuerySmartContractStateRequest, opts ...grpc.CallOption) (*wasmtypes.QuerySmartContractStateResponse, error) {
if m.SmartContractStateFunc != nil {
return m.SmartContractStateFunc(ctx, in, opts...)
}
panic("MockQueryClient.SmartContractState unimplemented")
}

func (m *WasmClient) WithSmartContractState(data wasmtypes.RawContractMessage, err error) {
m.SmartContractStateFunc = func(ctx context.Context, in *wasmtypes.QuerySmartContractStateRequest, opts ...grpc.CallOption) (*wasmtypes.QuerySmartContractStateResponse, error) {
return &wasmtypes.QuerySmartContractStateResponse{
Data: data,
}, err
}
}

func (m *WasmClient) Code(ctx context.Context, in *wasmtypes.QueryCodeRequest, opts ...grpc.CallOption) (*wasmtypes.QueryCodeResponse, error) {
if m.CodeFunc != nil {
return m.CodeFunc(ctx, in, opts...)
}
panic("MockQueryClient.Code unimplemented")
}

func (m *WasmClient) Codes(ctx context.Context, in *wasmtypes.QueryCodesRequest, opts ...grpc.CallOption) (*wasmtypes.QueryCodesResponse, error) {
if m.CodesFunc != nil {
return m.CodesFunc(ctx, in, opts...)
}
panic("MockQueryClient.Codes unimplemented")
}

func (m *WasmClient) PinnedCodes(ctx context.Context, in *wasmtypes.QueryPinnedCodesRequest, opts ...grpc.CallOption) (*wasmtypes.QueryPinnedCodesResponse, error) {
if m.PinnedCodesFunc != nil {
return m.PinnedCodesFunc(ctx, in, opts...)
}
panic("MockQueryClient.PinnedCodes unimplemented")
}

func (m *WasmClient) Params(ctx context.Context, in *wasmtypes.QueryParamsRequest, opts ...grpc.CallOption) (*wasmtypes.QueryParamsResponse, error) {
if m.ParamsFunc != nil {
return m.ParamsFunc(ctx, in, opts...)
}
panic("MockQueryClient.Params unimplemented")
}

func (m *WasmClient) ContractsByCreator(ctx context.Context, in *wasmtypes.QueryContractsByCreatorRequest, opts ...grpc.CallOption) (*wasmtypes.QueryContractsByCreatorResponse, error) {
if m.ContractsByCreatorFunc != nil {
return m.ContractsByCreatorFunc(ctx, in, opts...)
}
panic("MockQueryClient.ContractsByCreator unimplemented")
}

func (m *WasmClient) BuildAddress(ctx context.Context, in *wasmtypes.QueryBuildAddressRequest, opts ...grpc.CallOption) (*wasmtypes.QueryBuildAddressResponse, error) {
if m.BuildAddressFunc != nil {
return m.BuildAddressFunc(ctx, in, opts...)
}
panic("MockQueryClient.BuildAddress unimplemented")
}
6 changes: 3 additions & 3 deletions router/usecase/pools/routable_concentrated_pool.go
Original file line number Diff line number Diff line change
Expand Up @@ -339,9 +339,9 @@ func (r *routableConcentratedPoolImpl) ChargeTakerFeeExactIn(tokenIn sdk.Coin) (

// ChargeTakerFeeExactOut implements domain.RoutablePool.
// Charges the taker fee for the given token out and returns the token out after the fee has been charged.
func (r *routableConcentratedPoolImpl) ChargeTakerFeeExactOut(tokenOut sdk.Coin) (tokenOutAfterFee sdk.Coin) {
tokenOutAfterTakerFee, _ := poolmanager.CalcTakerFeeExactOut(tokenOut, r.GetTakerFee())
return tokenOutAfterTakerFee
func (r *routableConcentratedPoolImpl) ChargeTakerFeeExactOut(tokenIn sdk.Coin) (tokenOutAfterFee sdk.Coin) {
tokenInAfterTakerFee, _ := poolmanager.CalcTakerFeeExactOut(tokenIn, r.GetTakerFee())
return tokenInAfterTakerFee
Comment on lines +342 to +344
Copy link
Member

Choose a reason for hiding this comment

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

Could you please link where this is being called for a CL pool? I'm not seeing where.

I believe the same problem might be present for other pools - please check, create a task, and do a follow-up if applicable

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

You're right, at the moment it is just APIs, there will be a follow up PRs with code calling those, actually I have already started working on this huge PR #607 and will open follow up smaller PRs from it later.

}

// SetTokenInDenom implements domain.RoutablePool.
Expand Down
37 changes: 32 additions & 5 deletions router/usecase/pools/routable_cw_pool.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ package pools

import (
"context"
"errors"
"fmt"

"cosmossdk.io/math"
Expand Down Expand Up @@ -86,8 +85,35 @@ func (r *routableCosmWasmPoolImpl) GetSpreadFactor() math.LegacyDec {
}

// CalculateTokenInByTokenOut implements domain.RoutablePool.
// It calculates the amount of token in given the amount of token out for a transmuter pool.
// Transmuter pool allows no slippage swaps. It just returns the same amount of token in as token out
// Returns error if:
// - the underlying chain pool set on the routable pool is not of transmuter type
// - the token out amount is greater than the balance of the token out
// - the token out amount is greater than the balance of the token in
func (r *routableCosmWasmPoolImpl) CalculateTokenInByTokenOut(ctx context.Context, tokenOut sdk.Coin) (sdk.Coin, error) {
return sdk.Coin{}, errors.New("not implemented")
return r.calculateTokenInByTokenOut(ctx, tokenOut, r.TokenInDenom)
}

func (r *routableCosmWasmPoolImpl) calculateTokenInByTokenOut(ctx context.Context, tokenOut sdk.Coin, tokenInDenom string) (sdk.Coin, error) {
poolType := r.GetType()

// Ensure that the pool is cosmwasm
if poolType != poolmanagertypes.CosmWasm {
return sdk.Coin{}, domain.InvalidPoolTypeError{PoolType: int32(poolType)}
}

// Configure the calc query message
calcMessage := msg.NewCalcInAmtGivenOutRequest(tokenInDenom, tokenOut, r.SpreadFactor)

calcInAmtGivenOutResponse := msg.CalcInAmtGivenOutResponse{}
if err := cosmwasmdomain.QueryCosmwasmContract(ctx, r.wasmClient, r.ChainPool.ContractAddress, &calcMessage, &calcInAmtGivenOutResponse); err != nil {
return sdk.Coin{}, err
}

// No slippage swaps - just return the same amount of token out as token in
// as long as there is enough liquidity in the pool.
return calcInAmtGivenOutResponse.TokenIn, nil
}

// CalculateTokenOutByTokenIn implements domain.RoutablePool.
Expand Down Expand Up @@ -155,9 +181,10 @@ func (r *routableCosmWasmPoolImpl) ChargeTakerFeeExactIn(tokenIn sdk.Coin) (inAm
}

// ChargeTakerFeeExactOut implements domain.RoutablePool.
// Returns tokenOutAmount and does not charge any fee for transmuter pools.
func (r *routableCosmWasmPoolImpl) ChargeTakerFeeExactOut(tokenOut sdk.Coin) (outAmountAfterFee sdk.Coin) {
return sdk.Coin{}
// Returns tokenInAmount and does not charge any fee for transmuter pools.
func (r *routableCosmWasmPoolImpl) ChargeTakerFeeExactOut(tokenIn sdk.Coin) (inAmountAfterFee sdk.Coin) {
Copy link
Member

Choose a reason for hiding this comment

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

Where is this being called?

tokenInAfterTakerFee, _ := poolmanager.CalcTakerFeeExactOut(tokenIn, r.GetTakerFee())
return tokenInAfterTakerFee
}

// GetTakerFee implements domain.RoutablePool.
Expand Down
Loading
Loading