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
3 changes: 1 addition & 2 deletions app/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ import (
"github.com/rs/zerolog/log"
"github.com/spf13/viper"
"github.com/sprintertech/lifi-solver/pkg/pricing"
lifiTypes "github.com/sprintertech/lifi-solver/pkg/protocols/lifi"
"github.com/sprintertech/lifi-solver/pkg/protocols/lifi/validation"
"github.com/sprintertech/lifi-solver/pkg/token"
"github.com/sprintertech/lifi-solver/pkg/tokenpricing/pyth"
Expand Down Expand Up @@ -289,7 +288,7 @@ func Run() error {
resolver := token.NewTokenResolver(solverConfig, usdPricer)
orderPricer := pricing.NewStandardPricer(resolver)
lifiApi := lifi.NewLifiAPI()
lifiValidator := validation.NewLifiEscrowOrderValidator[lifiTypes.LifiOrder](solverConfig, orderPricer)
lifiValidator := validation.NewLifiEscrowOrderValidator(solverConfig, orderPricer)

lifiMh := evmMessage.NewLifiEscrowMessageHandler(
*c.GeneralChainConfig.Id,
Expand Down
19 changes: 7 additions & 12 deletions chains/evm/message/lifiEscrow.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import (
"encoding/json"
"fmt"
"math/big"
"strconv"

"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/common/hexutil"
Expand Down Expand Up @@ -139,7 +138,7 @@ func (h *LifiEscrowMessageHandler) HandleMessage(m *message.Message) (*proposal.
[]common.Address{borrowToken},
new(big.Int).SetUint64(destChainID),
h.lifiAddresses[destChainID],
uint64(order.Order.FillDeadline),
big.NewInt(order.Order.FillDeadline.Unix()).Uint64(),
data.Caller,
data.LiquidityPool,
data.Nonce,
Expand Down Expand Up @@ -168,11 +167,7 @@ func (h *LifiEscrowMessageHandler) HandleMessage(m *message.Message) (*proposal.
}

func (h *LifiEscrowMessageHandler) borrowToken(order *lifi.LifiOrder) (common.Address, uint64, error) {
destChainID, err := strconv.ParseUint(order.Order.Outputs[0].ChainID, 10, 64)
if err != nil {
return common.Address{}, 0, err
}

destChainID := order.Order.Outputs[0].ChainID
tokenIn := common.BytesToAddress(order.GenericInputs[0].TokenAddress[:])
symbol, _, err := h.tokenStore.ConfigByAddress(h.chainID, tokenIn)
if err != nil {
Expand Down Expand Up @@ -200,7 +195,7 @@ func (h *LifiEscrowMessageHandler) calldata(order *lifi.LifiOrder) ([]byte, erro
}
outputs := make([]output, len(order.Order.Outputs))
for i, o := range order.Order.Outputs {
chainID, _ := new(big.Int).SetString(o.ChainID, 10)
chainID := new(big.Int).SetUint64(o.ChainID)
call, err := hexutil.Decode(o.Call)
if err != nil {
return nil, err
Expand All @@ -210,11 +205,11 @@ func (h *LifiEscrowMessageHandler) calldata(order *lifi.LifiOrder) ([]byte, erro
return nil, err
}
outputs[i] = output{
Oracle: common.HexToHash(o.Oracle),
Settler: common.HexToHash(o.Settler),
Oracle: *o.Oracle,
Settler: *o.Settler,
ChainId: chainID,
Amount: o.Amount.Int,
Recipient: common.HexToHash(o.Recipient),
Recipient: *o.Recipient,
Call: call,
Context: context,
}
Expand All @@ -224,7 +219,7 @@ func (h *LifiEscrowMessageHandler) calldata(order *lifi.LifiOrder) ([]byte, erro
"fillOrderOutputs",
common.HexToHash(order.Meta.OnChainOrderID),
outputs,
new(big.Int).SetUint64(uint64(order.Order.FillDeadline)),
big.NewInt(order.Order.FillDeadline.Unix()),
common.HexToHash(h.mpcAddress.Hex()).Bytes())
}

Expand Down
14 changes: 7 additions & 7 deletions chains/evm/message/lifiEscrow_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,14 +55,14 @@ func (s *LifiEscrowMessageHandlerTestSuite) SetupTest() {

tokens := make(map[uint64]map[string]config.TokenConfig)
tokens[42161] = make(map[string]config.TokenConfig)
tokens[42161]["WETH"] = config.TokenConfig{
Address: common.HexToAddress("0x036CbD53842c5426634e7929541eC2318f3dCF7e"),
Decimals: 18,
tokens[42161]["USDC"] = config.TokenConfig{
Address: common.HexToAddress("0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913"),
Decimals: 6,
}
tokens[8453] = make(map[string]config.TokenConfig)
tokens[8453]["WETH"] = config.TokenConfig{
Address: common.HexToAddress("0x1c7D4B196Cb0C7B01d743Fbc6116a902379C7238"),
Decimals: 18,
tokens[8453]["USDC"] = config.TokenConfig{
Address: common.HexToAddress("0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913"),
Decimals: 6,
}
tokenStore := config.TokenStore{
Tokens: tokens,
Expand Down Expand Up @@ -150,7 +150,7 @@ func (s *LifiEscrowMessageHandlerTestSuite) Test_HandleMessage_BorrowAmountExcee
ErrChn: errChn,
Nonce: big.NewInt(101),
LiquidityPool: common.HexToAddress("0xe59aaf21c4D9Cf92d9eD4537f4404BA031f83b23"),
BorrowAmount: big.NewInt(20001),
BorrowAmount: big.NewInt(100001),
OrderID: "orderID",
}
s.mockOrderFetcher.EXPECT().GetOrder("orderID").Return(s.mockOrder, nil)
Expand Down
4 changes: 2 additions & 2 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,8 @@ 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 v0.0.0-20251008075555-6feaf23baf0b
github.com/sprintertech/solver-config/go v0.0.0-20251002094949-6a71816a6ac9
github.com/sprintertech/lifi-solver v0.0.0-20251009144421-521a5d0efa84
github.com/sprintertech/solver-config/go v0.0.0-20251003113310-77bd6669a2ef
github.com/stretchr/testify v1.10.0
github.com/sygmaprotocol/sygma-core v0.0.0-20250304150334-bd39ac4f7b82
go.opentelemetry.io/otel v1.16.0
Expand Down
4 changes: 4 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -946,8 +946,12 @@ github.com/sprintertech/lifi-solver v0.0.0-20251001133701-76403ab387a0 h1:z6hwK1
github.com/sprintertech/lifi-solver v0.0.0-20251001133701-76403ab387a0/go.mod h1:h8+7mUc7+adJCAhYf70jvSJp2mc38aLGulBu1zSUlQ8=
github.com/sprintertech/lifi-solver v0.0.0-20251008075555-6feaf23baf0b h1:kjEY1836p/5xHhM+noJvzCwbcbfKdPFCY+H5V9snUpc=
github.com/sprintertech/lifi-solver v0.0.0-20251008075555-6feaf23baf0b/go.mod h1:h8+7mUc7+adJCAhYf70jvSJp2mc38aLGulBu1zSUlQ8=
github.com/sprintertech/lifi-solver v0.0.0-20251009144421-521a5d0efa84 h1:ZygoYNw7Dlnxc3U+o8trzmbSWkH+l7lIUlBSWYIrVvo=
github.com/sprintertech/lifi-solver v0.0.0-20251009144421-521a5d0efa84/go.mod h1:EbAH3JJxioBVuHvyjaP5zTh6uPmumCpbE93WEjwpRm0=
github.com/sprintertech/solver-config/go v0.0.0-20251002094949-6a71816a6ac9 h1:1LzvyGBjEATGzByECJjgY7bj7dPN979VEzyOQLphAmM=
github.com/sprintertech/solver-config/go v0.0.0-20251002094949-6a71816a6ac9/go.mod h1:MrIGW6M815PSYKtWSeOd1Z7eiSeOIk/uA/6E2PhlQVQ=
github.com/sprintertech/solver-config/go v0.0.0-20251003113310-77bd6669a2ef h1:WPyHT8WM/f5rRFmzxeuTvuI6MCqM7wvTeBsW/B7y3lk=
github.com/sprintertech/solver-config/go v0.0.0-20251003113310-77bd6669a2ef/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=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
Expand Down
9 changes: 3 additions & 6 deletions protocol/lifi/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ func NewLifiAPI() *LifiAPI {

// GetOrder fetches order from the LiFi API by its on-chain orderID
func (a *LifiAPI) GetOrder(orderID string) (*lifi.LifiOrder, error) {
url := fmt.Sprintf("%s/orders?onChainOrderId=%s", LIFI_URL, orderID)
url := fmt.Sprintf("%s/orders/status?onChainOrderId=0x%s", LIFI_URL, orderID)
resp, err := a.HTTPClient.Get(url)
if err != nil {
return nil, fmt.Errorf("request failed: %w", err)
Expand All @@ -48,13 +48,10 @@ func (a *LifiAPI) GetOrder(orderID string) (*lifi.LifiOrder, error) {
return nil, fmt.Errorf("failed to read response body: %w", err)
}

s := new(Response)
s := new(lifi.LifiOrder)
if err := json.Unmarshal(body, s); err != nil {
return nil, fmt.Errorf("failed to unmarshal JSON: %w", err)
}
if len(s.Data) == 0 {
return nil, fmt.Errorf("no order found")
}

return &s.Data[0], nil
return s, nil
}
8 changes: 6 additions & 2 deletions protocol/lifi/api_test.go
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
//nolint:gocognit
package lifi_test

import (
Expand Down Expand Up @@ -64,7 +65,7 @@ func Test_LifiAPI_GetOrder(t *testing.T) {
t.Run(tc.name, func(t *testing.T) {
client := lifi.NewLifiAPI()
client.HTTPClient.Transport = roundTripperFunc(func(req *http.Request) (*http.Response, error) {
expectedURL := fmt.Sprintf("%s/orders?onChainOrderId=%s", lifi.LIFI_URL, tc.id)
expectedURL := fmt.Sprintf("%s/orders/status?onChainOrderId=0x%s", lifi.LIFI_URL, tc.id)
if req.URL.String() != expectedURL {
return nil, fmt.Errorf("unexpected URL: got %s, want %s", req.URL.String(), expectedURL)
}
Expand Down Expand Up @@ -96,7 +97,10 @@ func Test_LifiAPI_GetOrder(t *testing.T) {
}

var want *lifiProtocol.LifiOrder
_ = json.Unmarshal(tc.wantResult, &want)
err = json.Unmarshal(tc.wantResult, &want)
if err != nil {
t.Fatalf("unexpected error: %v", err)
}
if !reflect.DeepEqual(got, want) {
t.Errorf("expected %+v, got %+v", tc.wantResult, got)
}
Expand Down
94 changes: 92 additions & 2 deletions protocol/lifi/mock/mockData.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,97 @@
package mock

const LifiMockResponse = `
{"data":[{"order":{"user":"0x529cebf485dee1d68073afb75244022f048b0157","nonce":"2824938975","inputs":[["36247376698627773575328963637012941151846014800421893333724382654794431230520","20000"]],"expires":1752648593,"outputs":[{"call":"0x","token":"0x000000000000000000000000036CbD53842c5426634e7929541eC2318f3dCF7e","amount":"10000","oracle":"0x000000000000000000000000ca200b41459BF9a1C7EA7F1F22610281Bfb3a8AB","chainId":"42161","context":"0x","settler":"0x000000000000000000000000df96516136684972CA74E8c98E01D0D495f34a0A","recipient":"0x000000000000000000000000529cebf485dee1d68073afb75244022f048b0157"}],"localOracle":"0xca200b41459BF9a1C7EA7F1F22610281Bfb3a8AB","fillDeadline":1752648593,"originChainId":"11155111"},"quote":{"toAsset":"0x036cbd53842c5426634e7929541ec2318f3dcf7e","toPrice":"1","discount":"1","fromAsset":"0x1c7d4b196cb0c7b01d743fbc6116a902379c7238","fromPrice":"1","intermediary":"1"},"sponsorSignature":"","allocatorSignature":"0xb3377ec479bb23dcc4ecf811013a53a9dfb02590d9521f6f76430a0c95a8b8fc4fc052dd32a5a5b6fcb0a5b13dd2fe7cd77ed300abc48552127f598b965ad0431c","inputSettler":"0xb0567293b367e8Ed99cd44cDa1743980F2e6BBB2","meta":{"submitTime":1752648005381,"orderStatus":"Signed","destinationAddress":"0x529cebf485dee1d68073afb75244022f048b0157","orderIdentifier":"co_m2wMeHVReMdTygn3lEIQCA1B5Fcgdx","onChainOrderId":"0xf2c4d82bd09af0430f978a96cf5d3444756bd7143691713e580702475409efc7","signedAt":"2025-07-16T06:40:05.379Z","expiredAt":null,"lastCompactDepositBlockNumber":"8774872"}}],"meta":{"total":1,"limit":50,"offset":0}}
{
"order": {
"user": "0x6C8A0c210C4C097270FA5df9b799d79A6887b11A",
"nonce": "834202471",
"inputs": [
[
"749071750893463290574776461331093852760741783827",
"100000"
]
],
"expires": "1760110167",
"outputs": [
{
"call": "0x",
"token": "0x000000000000000000000000af88d065e77c8cc2239327c5edb3a432268e5831",
"amount": "100000",
"oracle": "0x0000000000000000000000000000006ea400569c0040d6e5ba651c00848409be",
"chainId": "42161",
"context": "0x",
"settler": "0x00000000000000000000000000000000d7278408ce7a490015577c41e57143a5",
"recipient": "0x0000000000000000000000006c8a0c210c4c097270fa5df9b799d79a6887b11a"
}
],
"inputOracle": "0x0000006EA400569c0040d6e5Ba651c00848409Be",
"fillDeadline": "1760110167",
"originChainId": "8453"
},
"quote": null,
"sponsorSignature": null,
"allocatorSignature": null,
"inputSettler": "0x000001bf3f3175bd007f3889b50000c7006e72c0",
"meta": {
"submitTime": 1760102985727,
"orderStatus": "Signed",
"destinationAddress": "0x6c8a0c210c4c097270fa5df9b799d79a6887b11a",
"orderIdentifier": "intent_F_MiaNxyjvyryvvh2OqsuINeqwFMjI",
"onChainOrderId": "0xe40eb815e8fd931b07ca5bb1be759861ff2a63348624fb5c374b2ee675430638",
"signedAt": "2025-10-10T13:29:37.000Z",
"expiredAt": null,
"lastCompactDepositBlockNumber": null,
"orderInitiatedTxHash": "0xe40e3258ebfd90ce75feea3859c204f50e14ee9b28f72d971b4cfaa41eedfba4",
"orderDeliveredTxHash": null,
"orderVerifiedTxHash": null,
"orderSettledTxHash": null
}
}
`

const ExpectedLifiResponse = `{"order":{"user":"0x529cebf485dee1d68073afb75244022f048b0157","nonce":"2824938975","inputs":[["36247376698627773575328963637012941151846014800421893333724382654794431230520","20000"]],"expires":1752648593,"outputs":[{"call":"0x","token":"0x000000000000000000000000036CbD53842c5426634e7929541eC2318f3dCF7e","amount":"10000","oracle":"0x000000000000000000000000ca200b41459BF9a1C7EA7F1F22610281Bfb3a8AB","chainId":"42161","context":"0x","settler":"0x000000000000000000000000df96516136684972CA74E8c98E01D0D495f34a0A","recipient":"0x000000000000000000000000529cebf485dee1d68073afb75244022f048b0157"}],"localOracle":"0xca200b41459BF9a1C7EA7F1F22610281Bfb3a8AB","fillDeadline":1752648593,"originChainId":"11155111"},"quote":{"toAsset":"0x036cbd53842c5426634e7929541ec2318f3dcf7e","toPrice":"1","discount":"1","fromAsset":"0x1c7d4b196cb0c7b01d743fbc6116a902379c7238","fromPrice":"1","intermediary":"1"},"sponsorSignature":"","allocatorSignature":"0xb3377ec479bb23dcc4ecf811013a53a9dfb02590d9521f6f76430a0c95a8b8fc4fc052dd32a5a5b6fcb0a5b13dd2fe7cd77ed300abc48552127f598b965ad0431c","inputSettler":"0xb0567293b367e8Ed99cd44cDa1743980F2e6BBB2","meta":{"submitTime":1752648005381,"orderStatus":"Signed","destinationAddress":"0x529cebf485dee1d68073afb75244022f048b0157","orderIdentifier":"co_m2wMeHVReMdTygn3lEIQCA1B5Fcgdx","onChainOrderId":"0xf2c4d82bd09af0430f978a96cf5d3444756bd7143691713e580702475409efc7","signedAt":"2025-07-16T06:40:05.379Z","expiredAt":null,"lastCompactDepositBlockNumber":"8774872"}}`
const ExpectedLifiResponse = ` {
"order": {
"user": "0x6C8A0c210C4C097270FA5df9b799d79A6887b11A",
"nonce": "834202471",
"inputs": [
[
"749071750893463290574776461331093852760741783827",
"100000"
]
],
"expires": "1760110167",
"outputs": [
{
"call": "0x",
"token": "0x000000000000000000000000af88d065e77c8cc2239327c5edb3a432268e5831",
"amount": "100000",
"oracle": "0x0000000000000000000000000000006ea400569c0040d6e5ba651c00848409be",
"chainId": "42161",
"context": "0x",
"settler": "0x00000000000000000000000000000000d7278408ce7a490015577c41e57143a5",
"recipient": "0x0000000000000000000000006c8a0c210c4c097270fa5df9b799d79a6887b11a"
}
],
"inputOracle": "0x0000006EA400569c0040d6e5Ba651c00848409Be",
"fillDeadline": "1760110167",
"originChainId": "8453"
},
"quote": null,
"sponsorSignature": null,
"allocatorSignature": null,
"inputSettler": "0x000001bf3f3175bd007f3889b50000c7006e72c0",
"meta": {
"submitTime": 1760102985727,
"orderStatus": "Signed",
"destinationAddress": "0x6c8a0c210c4c097270fa5df9b799d79a6887b11a",
"orderIdentifier": "intent_F_MiaNxyjvyryvvh2OqsuINeqwFMjI",
"onChainOrderId": "0xe40eb815e8fd931b07ca5bb1be759861ff2a63348624fb5c374b2ee675430638",
"signedAt": "2025-10-10T13:29:37.000Z",
"expiredAt": null,
"lastCompactDepositBlockNumber": null,
"orderInitiatedTxHash": "0xe40e3258ebfd90ce75feea3859c204f50e14ee9b28f72d971b4cfaa41eedfba4",
"orderDeliveredTxHash": null,
"orderVerifiedTxHash": null,
"orderSettledTxHash": null
}
}`
Loading