-
Notifications
You must be signed in to change notification settings - Fork 13
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
9115718
commit 5ffd121
Showing
5 changed files
with
354 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
package types | ||
|
||
// CandidatePool is a data structure representing a | ||
// candidate pool to be used for routing. | ||
type CandidatePool struct { | ||
ID uint64 | ||
TokenOutDenom string | ||
} | ||
|
||
// CandidateRoute is a data structure representing a | ||
// candidate route to be used for routing. | ||
type CandidateRoute struct { | ||
Pools []CandidatePool | ||
IsCanonicalOrderboolRoute bool | ||
} | ||
|
||
// CandidateRoutes is a data structure representing a | ||
// list of candidate routes to be used for routing. | ||
// Additionally, it encapsulates a map of unique pool IDs | ||
// contained in the routes. | ||
type CandidateRoutes struct { | ||
Routes []CandidateRoute | ||
UniquePoolIDs map[uint64]struct{} | ||
ContainsCanonicalOrderbook bool | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,91 @@ | ||
package types | ||
|
||
import ( | ||
"testing" | ||
|
||
"github.com/stretchr/testify/assert" | ||
|
||
sqspassthroughdomain "github.com/osmosis-labs/osmosis/v28/ingest/types/passthroughdomain" | ||
api "github.com/osmosis-labs/sqs/pkg/api/v1beta1/pools" | ||
) | ||
|
||
func TestPoolWrapper_Incentive(t *testing.T) { | ||
tests := []struct { | ||
name string | ||
aprData sqspassthroughdomain.PoolAPRDataStatusWrap | ||
expected api.IncentiveType | ||
}{ | ||
{ | ||
name: "Superfluid Incentive", | ||
aprData: sqspassthroughdomain.PoolAPRDataStatusWrap{ | ||
PoolAPR: sqspassthroughdomain.PoolAPR{ | ||
SuperfluidAPR: sqspassthroughdomain.PoolDataRange{Lower: 1, Upper: 2}, | ||
OsmosisAPR: sqspassthroughdomain.PoolDataRange{Lower: 0, Upper: 0}, | ||
}, | ||
}, | ||
expected: api.IncentiveType_SUPERFLUID, | ||
}, | ||
{ | ||
name: "Osmosis Incentive", | ||
aprData: sqspassthroughdomain.PoolAPRDataStatusWrap{ | ||
PoolAPR: sqspassthroughdomain.PoolAPR{ | ||
SuperfluidAPR: sqspassthroughdomain.PoolDataRange{Lower: 0, Upper: 0}, | ||
OsmosisAPR: sqspassthroughdomain.PoolDataRange{Lower: 1, Upper: 2}, | ||
BoostAPR: sqspassthroughdomain.PoolDataRange{Lower: 0, Upper: 0}, | ||
}, | ||
}, | ||
expected: api.IncentiveType_OSMOSIS, | ||
}, | ||
{ | ||
name: "Boost Incentive", | ||
aprData: sqspassthroughdomain.PoolAPRDataStatusWrap{ | ||
PoolAPR: sqspassthroughdomain.PoolAPR{ | ||
BoostAPR: sqspassthroughdomain.PoolDataRange{Lower: 1, Upper: 2}, | ||
}, | ||
}, | ||
expected: api.IncentiveType_BOOST, | ||
}, | ||
{ | ||
name: "No Incentive", | ||
aprData: sqspassthroughdomain.PoolAPRDataStatusWrap{ | ||
PoolAPR: sqspassthroughdomain.PoolAPR{ | ||
SuperfluidAPR: sqspassthroughdomain.PoolDataRange{Lower: 0, Upper: 0}, | ||
OsmosisAPR: sqspassthroughdomain.PoolDataRange{Lower: 0, Upper: 0}, | ||
BoostAPR: sqspassthroughdomain.PoolDataRange{Lower: 0, Upper: 0}, | ||
}, | ||
}, | ||
expected: api.IncentiveType_NONE, | ||
}, | ||
{ | ||
name: "Multiple Incentives - Superfluid Priority", | ||
aprData: sqspassthroughdomain.PoolAPRDataStatusWrap{ | ||
PoolAPR: sqspassthroughdomain.PoolAPR{ | ||
SuperfluidAPR: sqspassthroughdomain.PoolDataRange{Lower: 1, Upper: 2}, | ||
OsmosisAPR: sqspassthroughdomain.PoolDataRange{Lower: 1, Upper: 2}, | ||
BoostAPR: sqspassthroughdomain.PoolDataRange{Lower: 1, Upper: 2}, | ||
}, | ||
}, | ||
expected: api.IncentiveType_SUPERFLUID, | ||
}, | ||
{ | ||
name: "Multiple Incentives - Osmosis Priority", | ||
aprData: sqspassthroughdomain.PoolAPRDataStatusWrap{ | ||
PoolAPR: sqspassthroughdomain.PoolAPR{ | ||
SuperfluidAPR: sqspassthroughdomain.PoolDataRange{Lower: 0, Upper: 0}, | ||
OsmosisAPR: sqspassthroughdomain.PoolDataRange{Lower: 1, Upper: 2}, | ||
BoostAPR: sqspassthroughdomain.PoolDataRange{Lower: 1, Upper: 2}, | ||
}, | ||
}, | ||
expected: api.IncentiveType_OSMOSIS, | ||
}, | ||
} | ||
|
||
for _, tt := range tests { | ||
t.Run(tt.name, func(t *testing.T) { | ||
pool := &PoolWrapper{ | ||
APRData: tt.aprData, | ||
} | ||
assert.Equal(t, tt.expected, pool.Incentive()) | ||
}) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
package types | ||
|
||
import "github.com/osmosis-labs/osmosis/osmomath" | ||
|
||
// TakerFeeForPair represents the taker fee for a pair of tokens | ||
type TakerFeeForPair struct { | ||
Denom0 string | ||
Denom1 string | ||
TakerFee osmomath.Dec | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,227 @@ | ||
package types | ||
|
||
import ( | ||
"fmt" | ||
"sort" | ||
"strings" | ||
|
||
"github.com/osmosis-labs/osmosis/osmomath" | ||
api "github.com/osmosis-labs/sqs/pkg/api/v1beta1/pools" | ||
|
||
ingesttypes "github.com/osmosis-labs/osmosis/v28/ingest/types" | ||
"github.com/osmosis-labs/osmosis/v28/ingest/types/passthroughdomain" | ||
poolmanagertypes "github.com/osmosis-labs/osmosis/v28/x/poolmanager/types" | ||
|
||
"cosmossdk.io/math" | ||
sdk "github.com/cosmos/cosmos-sdk/types" | ||
) | ||
|
||
type ( | ||
TakerFeeMap = ingesttypes.TakerFeeMap | ||
TickModel = ingesttypes.TickModel | ||
SQSPool = ingesttypes.SQSPool | ||
DenomPair = ingesttypes.DenomPair | ||
LiquidityDepthsWithRange = ingesttypes.LiquidityDepthsWithRange | ||
) | ||
|
||
var DefaultTakerFee = ingesttypes.DefaultTakerFee | ||
|
||
type PoolI interface { | ||
ingesttypes.PoolI | ||
|
||
// GetAPRData gets the APR data for the pool | ||
GetAPRData() passthroughdomain.PoolAPRDataStatusWrap | ||
|
||
// SetAPRData sets the APR data for the pool | ||
SetAPRData(aprData passthroughdomain.PoolAPRDataStatusWrap) | ||
|
||
// GetFeesData gets the fees data for the pool | ||
GetFeesData() passthroughdomain.PoolFeesDataStatusWrap | ||
|
||
// SetFeesData sets the fees data for the pool | ||
SetFeesData(feesData passthroughdomain.PoolFeesDataStatusWrap) | ||
|
||
// GetLiquidityCap returns the pool liquidity capitalization | ||
GetLiquidityCap() osmomath.Int | ||
|
||
// SetLiquidityCap sets the liquidity capitalization to the given | ||
// value. | ||
SetLiquidityCap(liquidityCap osmomath.Int) | ||
|
||
// GetLiquidityCapError returns the pool liquidity capitalization error. | ||
GetLiquidityCapError() string | ||
|
||
// SetLiquidityCapError sets the liquidity capitalization error | ||
SetLiquidityCapError(liquidityCapError string) | ||
|
||
// SetTickModel sets the tick model for the pool | ||
// If this is not a concentrated pool, errors | ||
SetTickModel(*TickModel) error | ||
|
||
// Incentive returns the incentive type for the pool | ||
Incentive() api.IncentiveType | ||
|
||
// Validate validates the pool | ||
// Returns nil if the pool is valid | ||
// Returns error if the pool is invalid | ||
Validate(minUOSMOTVL osmomath.Int) error | ||
} | ||
|
||
var _ PoolI = &PoolWrapper{} | ||
|
||
type PoolWrapper struct { | ||
ChainModel poolmanagertypes.PoolI `json:"underlying_pool"` | ||
SQSModel ingesttypes.SQSPool `json:"sqs_model"` | ||
APRData passthroughdomain.PoolAPRDataStatusWrap `json:"apr_data,omitempty"` | ||
FeesData passthroughdomain.PoolFeesDataStatusWrap `json:"fees_data,omitempty"` | ||
TickModel *ingesttypes.TickModel `json:"tick_model,omitempty"` | ||
} | ||
|
||
func NewPool(model poolmanagertypes.PoolI, spreadFactor osmomath.Dec, balances sdk.Coins) *PoolWrapper { | ||
return &PoolWrapper{ | ||
ChainModel: model, | ||
SQSModel: SQSPool{ | ||
SpreadFactor: spreadFactor, | ||
Balances: balances, | ||
}, | ||
} | ||
} | ||
|
||
// GetId implements PoolI. | ||
func (p *PoolWrapper) GetId() uint64 { | ||
return p.ChainModel.GetId() | ||
} | ||
|
||
// GetType implements PoolI. | ||
func (p *PoolWrapper) GetType() poolmanagertypes.PoolType { | ||
return p.ChainModel.GetType() | ||
} | ||
|
||
// GetPoolLiquidityCap implements PoolI. | ||
func (p *PoolWrapper) GetPoolLiquidityCap() osmomath.Int { | ||
return p.SQSModel.PoolLiquidityCap | ||
} | ||
|
||
// GetPoolDenoms implements PoolI. | ||
func (p *PoolWrapper) GetPoolDenoms() []string { | ||
// sort pool denoms | ||
sort.Strings(p.SQSModel.PoolDenoms) | ||
return p.SQSModel.PoolDenoms | ||
} | ||
|
||
// GetUnderlyingPool implements PoolI. | ||
func (p *PoolWrapper) GetUnderlyingPool() poolmanagertypes.PoolI { | ||
return p.ChainModel | ||
} | ||
|
||
// GetSQSPoolModel implements PoolI. | ||
func (p *PoolWrapper) GetSQSPoolModel() SQSPool { | ||
return p.SQSModel | ||
} | ||
|
||
// GetTickModel implements PoolI. | ||
func (p *PoolWrapper) GetTickModel() (*TickModel, error) { | ||
if p.GetType() != poolmanagertypes.Concentrated { | ||
return nil, fmt.Errorf("pool (%d) is not a concentrated pool, type (%d)", p.GetId(), p.GetType()) | ||
} | ||
|
||
if p.TickModel == nil { | ||
return nil, ingesttypes.ConcentratedPoolNoTickModelError{PoolId: p.GetId()} | ||
} | ||
|
||
return p.TickModel, nil | ||
} | ||
|
||
// Incentive implements PoolI. | ||
func (p *PoolWrapper) Incentive() api.IncentiveType { | ||
apr := p.GetAPRData() | ||
|
||
checks := []struct { | ||
apr passthroughdomain.PoolDataRange | ||
incentive api.IncentiveType | ||
}{ | ||
{apr.SuperfluidAPR, api.IncentiveType_SUPERFLUID}, | ||
{apr.OsmosisAPR, api.IncentiveType_OSMOSIS}, | ||
{apr.BoostAPR, api.IncentiveType_BOOST}, | ||
} | ||
|
||
for _, check := range checks { | ||
if check.apr.Lower != 0 && check.apr.Upper != 0 { | ||
return check.incentive | ||
} | ||
} | ||
|
||
return api.IncentiveType_NONE | ||
} | ||
|
||
// SetTickModel implements PoolI. | ||
func (p *PoolWrapper) SetTickModel(tickModel *TickModel) error { | ||
if p.GetType() != poolmanagertypes.Concentrated { | ||
return fmt.Errorf("pool (%d) is not a concentrated pool, type (%d)", p.GetId(), p.GetType()) | ||
} | ||
|
||
p.TickModel = tickModel | ||
|
||
return nil | ||
} | ||
|
||
func (p *PoolWrapper) Validate(minPoolLiquidityCapitalization osmomath.Int) error { | ||
sqsModel := p.GetSQSPoolModel() | ||
poolDenoms := p.GetPoolDenoms() | ||
|
||
if len(poolDenoms) < 2 { | ||
return fmt.Errorf("pool (%d) has fewer than 2 denoms (%d)", p.GetId(), len(poolDenoms)) | ||
} | ||
|
||
// Note that balances are allowed to be zero because zero coins are filtered out. | ||
|
||
// Validate pool liquidity capitalization. | ||
// If there is no pool liquidity capitalization error set and the pool liquidity capitalization is nil or zero, return an error. This implies | ||
// That pool has no liquidity. | ||
poolLiquidityCapError := strings.TrimSpace(p.SQSModel.PoolLiquidityCapError) | ||
if poolLiquidityCapError == "" && (sqsModel.PoolLiquidityCap.IsNil() || sqsModel.PoolLiquidityCap.IsZero()) { | ||
return fmt.Errorf("pool (%d) has no liquidity, minimum pool liquidity capitalization (%s)", p.GetId(), minPoolLiquidityCapitalization) | ||
} | ||
|
||
return nil | ||
} | ||
|
||
// GetLiquidityCap implements PoolI. | ||
func (p *PoolWrapper) GetLiquidityCap() osmomath.Int { | ||
return p.SQSModel.PoolLiquidityCap | ||
} | ||
|
||
// SetLiquidityCap implements PoolI. | ||
func (p *PoolWrapper) SetLiquidityCap(liquidityCap math.Int) { | ||
p.SQSModel.PoolLiquidityCap = liquidityCap | ||
} | ||
|
||
// GetLiquidityCapError implements PoolI. | ||
func (p *PoolWrapper) GetLiquidityCapError() string { | ||
return p.SQSModel.PoolLiquidityCapError | ||
} | ||
|
||
// SetLiquidityCapError implements PoolI. | ||
func (p *PoolWrapper) SetLiquidityCapError(liquidityCapError string) { | ||
p.SQSModel.PoolLiquidityCapError = liquidityCapError | ||
} | ||
|
||
// SetAPRData implements PoolI. | ||
func (p *PoolWrapper) SetAPRData(aprData passthroughdomain.PoolAPRDataStatusWrap) { | ||
p.APRData = aprData | ||
} | ||
|
||
// SetFeesData implements PoolI. | ||
func (p *PoolWrapper) SetFeesData(feesData passthroughdomain.PoolFeesDataStatusWrap) { | ||
p.FeesData = feesData | ||
} | ||
|
||
// GetAPRData implements PoolI. | ||
func (p *PoolWrapper) GetAPRData() passthroughdomain.PoolAPRDataStatusWrap { | ||
return p.APRData | ||
} | ||
|
||
// GetFeesData implements PoolI. | ||
func (p *PoolWrapper) GetFeesData() passthroughdomain.PoolFeesDataStatusWrap { | ||
return p.FeesData | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters