Skip to content

Commit

Permalink
Feat: add MinRebalanceAmount with tests
Browse files Browse the repository at this point in the history
  • Loading branch information
dwasse committed Mar 13, 2024
1 parent f6e4834 commit 11e1ac4
Show file tree
Hide file tree
Showing 4 changed files with 57 additions and 3 deletions.
6 changes: 6 additions & 0 deletions services/rfq/relayer/inventory/manager.go
Original file line number Diff line number Diff line change
Expand Up @@ -472,6 +472,12 @@ func getRebalance(span trace.Span, cfg relconfig.Config, tokens map[int]map[comm
return nil, nil
}

// clip the rebalance amount by the configured min
minAmount := cfg.GetMinRebalanceAmount(maxTokenData.ChainID, maxTokenData.Addr)
if amount.Cmp(minAmount) < 0 {
amount = minAmount
}

// clip the rebalance amount by the configured max
maxAmount := cfg.GetMaxRebalanceAmount(maxTokenData.ChainID, maxTokenData.Addr)
if amount.Cmp(maxAmount) > 0 {
Expand Down
20 changes: 17 additions & 3 deletions services/rfq/relayer/inventory/manager_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ func (i *InventoryTestSuite) TestGetRebalance() {
usdcDataDest.Addr: &usdcDataDest,
},
}
getConfig := func(maxRebalanceAmount string) relconfig.Config {
getConfig := func(minRebalanceAmount, maxRebalanceAmount string) relconfig.Config {
return relconfig.Config{
Chains: map[int]relconfig.ChainConfig{
origin: {
Expand All @@ -98,6 +98,7 @@ func (i *InventoryTestSuite) TestGetRebalance() {
Decimals: 6,
MaintenanceBalancePct: 20,
InitialBalancePct: 50,
MinRebalanceAmount: minRebalanceAmount,
MaxRebalanceAmount: maxRebalanceAmount,
},
},
Expand All @@ -109,6 +110,7 @@ func (i *InventoryTestSuite) TestGetRebalance() {
Decimals: 6,
MaintenanceBalancePct: 20,
InitialBalancePct: 50,
MinRebalanceAmount: minRebalanceAmount,
MaxRebalanceAmount: maxRebalanceAmount,
},
},
Expand All @@ -120,6 +122,7 @@ func (i *InventoryTestSuite) TestGetRebalance() {
Decimals: 6,
MaintenanceBalancePct: 0,
InitialBalancePct: 0,
MinRebalanceAmount: minRebalanceAmount,
MaxRebalanceAmount: maxRebalanceAmount,
},
},
Expand All @@ -129,7 +132,7 @@ func (i *InventoryTestSuite) TestGetRebalance() {
}

// 10 USDC on both chains; no rebalance needed
cfg := getConfig("")
cfg := getConfig("", "")
usdcDataOrigin.Balance = big.NewInt(1e7)
usdcDataDest.Balance = big.NewInt(1e7)
rebalance, err := inventory.GetRebalance(cfg, tokens, origin, usdcDataOrigin.Addr)
Expand All @@ -148,8 +151,19 @@ func (i *InventoryTestSuite) TestGetRebalance() {
}
i.Equal(expected, rebalance)

// Set min rebalance amount
cfgWithMax := getConfig("10", "1000000000")
rebalance, err = inventory.GetRebalance(cfgWithMax, tokens, origin, usdcDataOrigin.Addr)
i.NoError(err)
expected = &inventory.RebalanceData{
OriginMetadata: &usdcDataOrigin,
DestMetadata: &usdcDataDest,
Amount: big.NewInt(1e7),
}
i.Equal(expected, rebalance)

// Set max rebalance amount
cfgWithMax := getConfig("1.1")
cfgWithMax = getConfig("0", "1.1")
rebalance, err = inventory.GetRebalance(cfgWithMax, tokens, origin, usdcDataOrigin.Addr)
i.NoError(err)
expected = &inventory.RebalanceData{
Expand Down
2 changes: 2 additions & 0 deletions services/rfq/relayer/relconfig/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,8 @@ type TokenConfig struct {
MaintenanceBalancePct float64 `yaml:"maintenance_balance_pct"`
// InitialBalancePct is the percentage of the total balance to retain when triggering a rebalance.
InitialBalancePct float64 `yaml:"initial_balance_pct"`
// MinRebalanceAmount is the minimum amount to rebalance in human-readable units.
MinRebalanceAmount string `yaml:"min_rebalance_amount"`
// MaxRebalanceAmount is the maximum amount to rebalance in human-readable units.
MaxRebalanceAmount string `yaml:"max_rebalance_amount"`
}
Expand Down
32 changes: 32 additions & 0 deletions services/rfq/relayer/relconfig/getters.go
Original file line number Diff line number Diff line change
Expand Up @@ -547,6 +547,38 @@ func (c Config) GetMinQuoteAmount(chainID int, addr common.Address) *big.Int {
return quoteAmountScaled
}

var defaultMinRebalanceAmount = big.NewInt(1000)

// GetMinRebalanceAmount returns the min rebalance amount for the given chain and address.
// Note that this getter returns the value in native token decimals.
func (c Config) GetMinRebalanceAmount(chainID int, addr common.Address) *big.Int {
chainCfg, ok := c.Chains[chainID]
if !ok {
return defaultMinRebalanceAmount
}

var tokenCfg *TokenConfig
for _, cfg := range chainCfg.Tokens {
if common.HexToAddress(cfg.Address).Hex() == addr.Hex() {
cfgCopy := cfg
tokenCfg = &cfgCopy
break
}
}
if tokenCfg == nil {
return defaultMinRebalanceAmount
}
rebalanceAmountFlt, ok := new(big.Float).SetString(tokenCfg.MinRebalanceAmount)
if !ok || rebalanceAmountFlt == nil {
return defaultMinRebalanceAmount
}

// Scale by the token decimals.
denomDecimalsFactor := new(big.Int).Exp(big.NewInt(10), big.NewInt(int64(tokenCfg.Decimals)), nil)
minRebalanceAmountScaled, _ := new(big.Float).Mul(rebalanceAmountFlt, new(big.Float).SetInt(denomDecimalsFactor)).Int(nil)
return minRebalanceAmountScaled
}

var defaultMaxRebalanceAmount = abi.MaxInt256

// GetMaxRebalanceAmount returns the max rebalance amount for the given chain and address.
Expand Down

0 comments on commit 11e1ac4

Please sign in to comment.