Skip to content
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
2 changes: 2 additions & 0 deletions api/handlers/signing.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ type SigningBody struct {
Calldata string `json:"calldata"`
DepositTxHash string `json:"depositTxHash"`
BorrowAmount *BigInt `json:"borrowAmount"`
BorrowToken string `json:"borrowToken"`
RepaymentChainId uint64 `json:"repaymentChainId"`
Deadline uint64 `json:"deadline"`
TokenOut string `json:"tokenOut"`
Expand Down Expand Up @@ -102,6 +103,7 @@ func (h *SigningHandler) HandleSigning(w http.ResponseWriter, r *http.Request) {
Destination: b.ChainId,
Deadline: b.Deadline,
BorrowAmount: b.BorrowAmount.Int,
BorrowToken: b.BorrowToken,
})
}
case LighterProtocol:
Expand Down
36 changes: 31 additions & 5 deletions app/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,18 @@ import (
"github.com/ethereum/go-ethereum/common"
ethereumCrypto "github.com/ethereum/go-ethereum/crypto"
"github.com/libp2p/go-libp2p/core/crypto"
"github.com/lmittmann/w3"
"github.com/rs/zerolog/log"
"github.com/spf13/viper"
"github.com/sprintertech/lifi-solver/pkg/pricing"
"github.com/sprintertech/lifi-solver/pkg/protocols"
"github.com/sprintertech/lifi-solver/pkg/protocols/erc4626"
"github.com/sprintertech/lifi-solver/pkg/protocols/lifi/validation"
"github.com/sprintertech/lifi-solver/pkg/router"
"github.com/sprintertech/lifi-solver/pkg/token"
"github.com/sprintertech/lifi-solver/pkg/tokenpricing/aggregator"
"github.com/sprintertech/lifi-solver/pkg/tokenpricing/pyth"
"github.com/sprintertech/lifi-solver/pkg/tokenpricing/vault"
solverConfig "github.com/sprintertech/solver-config/go/config"
"github.com/sprintertech/sprinter-signing/api"
"github.com/sprintertech/sprinter-signing/api/handlers"
Expand Down Expand Up @@ -65,6 +69,10 @@ import (

var Version string

const (
ETHEREUM uint64 = 1
)

//nolint:gocognit
func Run() error {
var err error
Expand Down Expand Up @@ -167,6 +175,11 @@ func Run() error {
mpcAddress = common.HexToAddress(solverConfig.ProtocolsMetadata.Sprinter.MpcAddress)
}

usdPricer := pyth.NewClient(ctx)
err = usdPricer.Start(ctx)
panicOnError(err)
multiPricer := aggregator.New(usdPricer)

Comment thread
mpetrun5 marked this conversation as resolved.
var hubPoolContract across.TokenMatcher
acrossPools := make(map[uint64]common.Address)
lifiOutputSettlers := make(map[uint64]common.Address)
Expand Down Expand Up @@ -271,14 +284,27 @@ func Run() error {
}

if c.LifiOutputSettler != "" {
usdPricer := pyth.NewClient(ctx)
err = usdPricer.Start(ctx)
panicOnError(err)

if *c.GeneralChainConfig.Id == ETHEREUM {
w3Client, err := w3.Dial(c.GeneralChainConfig.Endpoint)
panicOnError(err)

roycoVault := common.HexToAddress(solverConfig.ProtocolsMetadata.Royco.Vault)
roycoVaultContract := erc4626.NewErc4626Contract(w3Client, &roycoVault)
vaultPricer := vault.NewPricer(
usdPricer,
[]vault.Vault{
vault.NewErc4626(roycoVaultContract, "srRoyUSDC", "USDC", 6),
},
time.Second*30,
)
multiPricer.Add(vaultPricer, "srRoyUSDC")
}
resolver := token.NewTokenResolver(solverConfig, multiPricer)

lifiConfig, err := lifiConfig.GetSolverConfig(solverConfig, protocols.LifiEscrow, lifiConfig.PulsarSolver)
panicOnError(err)

resolver := token.NewTokenResolver(solverConfig, usdPricer)
orderPricer := pricing.NewStandardPricer(resolver)
lifiApi := lifi.NewLifiEventFetcher(
client,
Expand All @@ -295,7 +321,7 @@ func Run() error {
communication,
keyshareStore,
watcher,
tokenStore,
resolver,
lifiApi,
orderPricer,
router.NewRouter(resolver, nil, nil, lifiConfig.Routes),
Expand Down
87 changes: 61 additions & 26 deletions chains/evm/message/lifiEscrow.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ import (
"github.com/sprintertech/sprinter-signing/chains/evm/calls/consts"
"github.com/sprintertech/sprinter-signing/chains/evm/signature"
"github.com/sprintertech/sprinter-signing/comm"
"github.com/sprintertech/sprinter-signing/config"
"github.com/sprintertech/sprinter-signing/tss"
"github.com/sprintertech/sprinter-signing/tss/ecdsa/signing"
"github.com/sygmaprotocol/sygma-core/relayer/message"
Expand All @@ -25,6 +24,7 @@ import (
"github.com/sprintertech/lifi-solver/pkg/pricing"
"github.com/sprintertech/lifi-solver/pkg/protocols/lifi"
"github.com/sprintertech/lifi-solver/pkg/router"
"github.com/sprintertech/lifi-solver/pkg/token"
)

type OrderFetcher interface {
Expand All @@ -43,7 +43,7 @@ type LifiEscrowMessageHandler struct {
confirmationWatcher ConfirmationWatcher

lifiAddresses map[uint64]common.Address
tokenStore config.TokenStore
tokenResolver token.TokenResolver
mpcAddress common.Address

orderFetcher OrderFetcher
Expand All @@ -64,7 +64,7 @@ func NewLifiEscrowMessageHandler(
comm comm.Communication,
fetcher signing.SaveDataFetcher,
confirmationWatcher ConfirmationWatcher,
tokenStore config.TokenStore,
tokenResolver token.TokenResolver,
orderFetcher OrderFetcher,
orderPricer pricing.OrderPricer,
router router.OrderRouter,
Expand All @@ -80,7 +80,7 @@ func NewLifiEscrowMessageHandler(
comm: comm,
fetcher: fetcher,
confirmationWatcher: confirmationWatcher,
tokenStore: tokenStore,
tokenResolver: tokenResolver,
orderFetcher: orderFetcher,
orderPricer: orderPricer,
validator: validator,
Expand Down Expand Up @@ -109,7 +109,7 @@ func (h *LifiEscrowMessageHandler) HandleMessage(m *message.Message) (*proposal.
return nil, err
}

err = h.verifyOrder(order, data.BorrowAmount)
err = h.verifyOrder(order)
if err != nil {
data.ErrChn <- err
return nil, err
Expand All @@ -121,7 +121,11 @@ func (h *LifiEscrowMessageHandler) HandleMessage(m *message.Message) (*proposal.
return nil, err
}

borrowToken, destChainID, err := h.borrowToken(order)
borrowToken, destChainID, err := h.borrowToken(
data,
order,
orderValue,
)
if err != nil {
data.ErrChn <- err
return nil, err
Expand Down Expand Up @@ -195,20 +199,65 @@ func (h *LifiEscrowMessageHandler) HandleMessage(m *message.Message) (*proposal.
return nil, nil
}

func (h *LifiEscrowMessageHandler) borrowToken(order *lifi.LifiOrder) (common.Address, uint64, error) {
func (h *LifiEscrowMessageHandler) borrowToken(
data *LifiEscrowData,
order *lifi.LifiOrder,
amountInValue float64,
) (common.Address, uint64, error) {
destChainID := order.Order.Outputs[0].ChainID
tokenIn := common.BytesToAddress(order.GenericInputs[0].TokenAddress[:])
symbol, _, err := h.tokenStore.ConfigByAddress(h.chainID, tokenIn)

tokenIn, err := h.tokenResolver.Token(
order.GenericInputs[0].ChainID,
*order.GenericInputs[0].TokenAddress)
if err != nil {
return common.Address{}, destChainID, err
}

destinationBorrowToken, err := h.tokenStore.ConfigBySymbol(destChainID, symbol)
tokenOut, err := h.tokenResolver.Token(
order.GenericOutputs[0].ChainID,
*order.GenericOutputs[0].TokenAddress)
if err != nil {
return common.Address{}, destChainID, err
}

return destinationBorrowToken.Address, destChainID, err
if data.BorrowToken != tokenIn.Symbol && data.BorrowToken != tokenOut.Symbol {
return common.Address{}, destChainID, fmt.Errorf(
"borrow token %s must be either input %s or output token symbol %s",
data.BorrowToken,
tokenIn.Symbol,
Comment thread
mpetrun5 marked this conversation as resolved.
tokenOut.Symbol)
}

if data.BorrowToken == tokenIn.Symbol {
dstToken, err := h.tokenResolver.TokenFromSymbol(
order.GenericOutputs[0].ChainID,
tokenIn.Symbol)
if err != nil {
return common.Address{}, destChainID, err
}

scaledInputAmount := chains.ScaleTokenAmount(
order.GenericInputs[0].Amount,
tokenIn.Decimals,
dstToken.Decimals)
if scaledInputAmount.Cmp(data.BorrowAmount) == -1 {
return common.Address{}, destChainID, fmt.Errorf(
"order input is less than requested borrow amount")
}

return common.BytesToAddress(dstToken.Address[:]), destChainID, nil
} else {
amountOutValue := tokenOut.AmountToUSD(data.BorrowAmount)
if amountInValue < amountOutValue {
return common.Address{}, destChainID, fmt.Errorf(
"order with destination borrow token has lower input amount value %f:%f",
Comment thread
mpetrun5 marked this conversation as resolved.
amountInValue,
amountOutValue,
)
}

return common.BytesToAddress(tokenOut.Address[:]), destChainID, nil
}
}

func (h *LifiEscrowMessageHandler) calldata(order *lifi.LifiOrder) ([]byte, error) {
Expand Down Expand Up @@ -254,7 +303,7 @@ func (h *LifiEscrowMessageHandler) calldata(order *lifi.LifiOrder) ([]byte, erro
}

// verifyOrder verifies order based on these instructions https://docs.catalyst.exchange/solver/orderflow/#order-validation
func (h *LifiEscrowMessageHandler) verifyOrder(order *lifi.LifiOrder, borrowAmount *big.Int) error {
func (h *LifiEscrowMessageHandler) verifyOrder(order *lifi.LifiOrder) error {
if len(order.Order.Inputs) > 1 || len(order.Order.Inputs) == 0 {
return fmt.Errorf("orders with multiple inputs not supported")
}
Expand All @@ -263,20 +312,6 @@ func (h *LifiEscrowMessageHandler) verifyOrder(order *lifi.LifiOrder, borrowAmou
return fmt.Errorf("orders with multiple outputs not supported")
}

tokenIn := common.BytesToAddress(order.GenericInputs[0].TokenAddress[:])
symbol, srcToken, err := h.tokenStore.ConfigByAddress(h.chainID, tokenIn)
if err != nil {
return err
}
dstToken, err := h.tokenStore.ConfigBySymbol(order.Order.Outputs[0].ChainID, symbol)
if err != nil {
return err
}
scaledInputAmount := chains.ScaleTokenAmount(order.GenericInputs[0].Amount, int64(srcToken.Decimals), int64(dstToken.Decimals))
if scaledInputAmount.Cmp(borrowAmount) == -1 {
return fmt.Errorf("order input is less than requested borrow amount")
}

augmentedOrder, err := order.AugmentedOrder(h.orderPricer, h.router)
if err != nil {
return err
Expand Down
1 change: 1 addition & 0 deletions chains/evm/message/message.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ type LifiEscrowData struct {
Caller common.Address
DepositTxHash string
BorrowAmount *big.Int
BorrowToken string
Deadline uint64
Nonce *big.Int
Source uint64
Expand Down
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ require (
github.com/rs/zerolog v1.25.0
github.com/spf13/cobra v1.8.1
github.com/spf13/viper v1.9.0
github.com/sprintertech/lifi-solver v1.10.1-0.20260504134943-9bcb16937adf
github.com/sprintertech/lifi-solver v1.12.7-0.20260512144109-aff2bb29e55a
github.com/sprintertech/solver-config/go v0.0.0-20260420164134-699e2fffda37
github.com/stretchr/testify v1.11.1
github.com/sygmaprotocol/sygma-core v0.0.0-20250304150334-bd39ac4f7b82
Expand Down
4 changes: 4 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -862,6 +862,10 @@ github.com/spf13/viper v1.9.0 h1:yR6EXjTp0y0cLN8OZg1CRZmOBdI88UcGkhgyJhu6nZk=
github.com/spf13/viper v1.9.0/go.mod h1:+i6ajR7OX2XaiBkrcZJFK21htRk7eDeLg7+O6bhUPP4=
github.com/sprintertech/lifi-solver v1.10.1-0.20260504134943-9bcb16937adf h1:VJ8iwyTEL0jJm9Mz+WUbUP/N5PeDynWUFT/LwvpGRDI=
github.com/sprintertech/lifi-solver v1.10.1-0.20260504134943-9bcb16937adf/go.mod h1:fGyHGX9kbFN7AtwCAvmQF+eu75vxr6JFLESfhXHlc70=
github.com/sprintertech/lifi-solver v1.12.6-0.20260511112454-9da73ca80e8e h1:RKtudMi7W6DMBqWhOsIPL8d+zpzzjwfQKD3nFAbDfQ8=
github.com/sprintertech/lifi-solver v1.12.6-0.20260511112454-9da73ca80e8e/go.mod h1:fGyHGX9kbFN7AtwCAvmQF+eu75vxr6JFLESfhXHlc70=
github.com/sprintertech/lifi-solver v1.12.7-0.20260512144109-aff2bb29e55a h1:1mpBylUWbaf2nNJ/EY1aP7D8DTYUHFjDpZTXLPdkScY=
github.com/sprintertech/lifi-solver v1.12.7-0.20260512144109-aff2bb29e55a/go.mod h1:fGyHGX9kbFN7AtwCAvmQF+eu75vxr6JFLESfhXHlc70=
github.com/sprintertech/solver-config/go v0.0.0-20260420164134-699e2fffda37 h1:cV00hOEI+SpQnaDyVxAjK199IbDEP5ONjTAmfg+HEb0=
github.com/sprintertech/solver-config/go v0.0.0-20260420164134-699e2fffda37/go.mod h1:MrIGW6M815PSYKtWSeOd1Z7eiSeOIk/uA/6E2PhlQVQ=
github.com/status-im/keycard-go v0.0.0-20190316090335-8537d3370df4/go.mod h1:RZLeN1LMWmRsyYjvAu+I6Dm9QmlDaIIt+Y+4Kd7Tp+Q=
Expand Down
Loading