Skip to content

Commit f14bd68

Browse files
committed
feat: validate lighter order value
1 parent 3fa5e7b commit f14bd68

File tree

5 files changed

+98
-6
lines changed

5 files changed

+98
-6
lines changed

app/app.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -391,6 +391,7 @@ func Run() error {
391391
lighterConfig.WithdrawalAddress,
392392
lighterConfig.UsdcAddress,
393393
lighterConfig.RepaymentAddress,
394+
lighterConfig.ConfirmationsByValue,
394395
lighterAPI,
395396
coordinator,
396397
host,

chains/lighter/config.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@ type LighterConfig struct {
1919
WithdrawalAddress common.Address
2020
UsdcAddress common.Address
2121
RepaymentAddress string
22+
// usd bucket -> confirmations
23+
ConfirmationsByValue map[uint64]uint64
2224
}
2325

2426
func NewLighterConfig(solverConfig solverConfig.SolverConfig) (*LighterConfig, error) {
@@ -37,6 +39,12 @@ func NewLighterConfig(solverConfig solverConfig.SolverConfig) (*LighterConfig, e
3739
return nil, fmt.Errorf("withdrawal address not configured")
3840
}
3941

42+
confirmations := make(map[uint64]uint64)
43+
for _, confirmation := range solverConfig.Chains[LIGHTER_CAIP].Confirmations {
44+
// nolint:gosec
45+
confirmations[uint64(confirmation.MaxAmountUSD)] = uint64(confirmation.Confirmations)
46+
}
47+
4048
return &LighterConfig{
4149
WithdrawalAddress: common.HexToAddress(withdrawalAddress),
4250
RepaymentAddress: solverConfig.ProtocolsMetadata.Lighter.RepaymentAddress,

chains/lighter/config_test.go

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -71,9 +71,23 @@ func (s *NewLighterConfigTestSuite) Test_ValidConfig() {
7171
Decimals: 6,
7272
}
7373

74+
expectedBlockConfirmations := make(map[uint64]uint64)
75+
expectedBlockConfirmations[1000] = 5
76+
expectedBlockConfirmations[2000] = 10
77+
7478
solverChains := make(map[string]solverConfig.Chain)
7579
solverChains["eip155:42161"] = solverConfig.Chain{
7680
Tokens: tokens,
81+
Confirmations: []solverConfig.Confirmations{
82+
{
83+
Confirmations: 5,
84+
MaxAmountUSD: 1000,
85+
},
86+
{
87+
Confirmations: 10,
88+
MaxAmountUSD: 2000,
89+
},
90+
},
7791
}
7892

7993
config, err := lighter.NewLighterConfig(solverConfig.SolverConfig{
@@ -90,8 +104,9 @@ func (s *NewLighterConfigTestSuite) Test_ValidConfig() {
90104

91105
s.Nil(err)
92106
s.Equal(config, &lighter.LighterConfig{
93-
WithdrawalAddress: common.HexToAddress("withdrawal"),
94-
UsdcAddress: common.HexToAddress("usdc"),
95-
RepaymentAddress: "3",
107+
WithdrawalAddress: common.HexToAddress("withdrawal"),
108+
UsdcAddress: common.HexToAddress("usdc"),
109+
RepaymentAddress: "3",
110+
ConfirmationsByValue: expectedBlockConfirmations,
96111
})
97112
}

chains/lighter/message/lighter.go

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,10 @@ import (
55
"encoding/json"
66
"errors"
77
"fmt"
8+
"maps"
9+
"math"
810
"math/big"
11+
"slices"
912
"strconv"
1013

1114
"github.com/ethereum/go-ethereum/common"
@@ -24,8 +27,9 @@ import (
2427
)
2528

2629
var (
27-
ARBITRUM_CHAIN_ID = big.NewInt(42161)
28-
USDC_ACCOUNT_INDEX uint64 = 3
30+
ARBITRUM_CHAIN_ID = big.NewInt(42161)
31+
USDC_ACCOUNT_INDEX uint64 = 3
32+
USDC_DECIMALS float64 = 6
2933
)
3034

3135
type Coordinator interface {
@@ -47,12 +51,14 @@ type LighterMessageHandler struct {
4751
usdcAddress common.Address
4852
repaymentAccount string
4953
txFetcher TxFetcher
54+
confirmations map[uint64]uint64
5055
}
5156

5257
func NewLighterMessageHandler(
5358
lighterAddress common.Address,
5459
usdcAddress common.Address,
5560
repaymentAccount string,
61+
confirmations map[uint64]uint64,
5662
txFetcher TxFetcher,
5763
coordinator Coordinator,
5864
host host.Host,
@@ -70,6 +76,7 @@ func NewLighterMessageHandler(
7076
comm: comm,
7177
fetcher: fetcher,
7278
sigChn: sigChn,
79+
confirmations: confirmations,
7380
}
7481
}
7582

@@ -149,9 +156,25 @@ func (h *LighterMessageHandler) verifyWithdrawal(tx *lighter.LighterTx) error {
149156
return errors.New("only usdc asset supported on lighter")
150157
}
151158

159+
if err := h.verifyOrderSize(tx.Transfer.Amount / uint64(math.Pow(10, USDC_DECIMALS))); err != nil {
160+
return err
161+
}
162+
152163
return nil
153164
}
154165

166+
func (h *LighterMessageHandler) verifyOrderSize(orderValue uint64) error {
167+
buckets := slices.Collect(maps.Keys(h.confirmations))
168+
slices.Sort(buckets)
169+
for _, bucket := range buckets {
170+
if orderValue < bucket {
171+
return nil
172+
}
173+
}
174+
175+
return fmt.Errorf("order value %d exceeds confirmation buckets", orderValue)
176+
}
177+
155178
func (h *LighterMessageHandler) calldata(tx *lighter.LighterTx) ([]byte, error) {
156179
return consts.LighterABI.Pack(
157180
"fulfillWithdraw",

chains/lighter/message/lighter_test.go

Lines changed: 46 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,11 +54,14 @@ func (s *LighterMessageHandlerTestSuite) SetupTest() {
5454
s.mockTxFetcher = mock_message.NewMockTxFetcher(ctrl)
5555

5656
s.sigChn = make(chan interface{}, 1)
57+
confirmations := make(map[uint64]uint64)
58+
confirmations[200] = 0
5759

5860
s.handler = message.NewLighterMessageHandler(
5961
common.Address{},
6062
common.Address{},
6163
"3",
64+
confirmations,
6265
s.mockTxFetcher,
6366
s.mockCoordinator,
6467
s.mockHost,
@@ -173,7 +176,7 @@ func (s *LighterMessageHandlerTestSuite) Test_HandleMessage_InvalidAsset() {
173176
DepositTxHash: "orderHash",
174177
}
175178
s.mockTxFetcher.EXPECT().GetTx(ad.OrderHash).Return(&lighter.LighterTx{
176-
Type: lighter.TxTypeL2Withdraw,
179+
Type: lighter.TxTypeL2Transfer,
177180
Transfer: &lighter.Transfer{
178181
Amount: 2000001,
179182
AssetIndex: 2,
@@ -238,6 +241,48 @@ func (s *LighterMessageHandlerTestSuite) Test_HandleMessage_InvalidAccount() {
238241
s.NotNil(err)
239242
}
240243

244+
func (s *LighterMessageHandlerTestSuite) Test_HandleMessage_InvalidOrderValue() {
245+
s.mockCommunication.EXPECT().Broadcast(
246+
gomock.Any(),
247+
gomock.Any(),
248+
comm.LighterMsg,
249+
"lighter",
250+
).Return(nil)
251+
p, _ := pstoremem.NewPeerstore()
252+
s.mockHost.EXPECT().Peerstore().Return(p)
253+
254+
errChn := make(chan error, 1)
255+
ad := &message.LighterData{
256+
ErrChn: errChn,
257+
Nonce: big.NewInt(101),
258+
LiquidityPool: common.HexToAddress("0xbe526bA5d1ad94cC59D7A79d99A59F607d31A657"),
259+
OrderHash: "orderHash",
260+
DepositTxHash: "orderHash",
261+
}
262+
s.mockTxFetcher.EXPECT().GetTx(ad.OrderHash).Return(&lighter.LighterTx{
263+
Type: lighter.TxTypeL2Transfer,
264+
Transfer: &lighter.Transfer{
265+
Amount: 200000001,
266+
AssetIndex: 3,
267+
ToAccountIndex: 3,
268+
Memo: []byte{238, 123, 250, 212, 202, 237, 62, 98, 106, 248, 169, 199, 213, 3, 76, 213, 137, 238, 73, 144, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
269+
},
270+
}, nil)
271+
272+
m := &coreMessage.Message{
273+
Data: ad,
274+
Source: 0,
275+
Destination: 10,
276+
}
277+
prop, err := s.handler.HandleMessage(m)
278+
279+
s.Nil(prop)
280+
s.NotNil(err)
281+
282+
err = <-errChn
283+
s.NotNil(err)
284+
}
285+
241286
func (s *LighterMessageHandlerTestSuite) Test_HandleMessage_MissingTx() {
242287
s.mockCommunication.EXPECT().Broadcast(
243288
gomock.Any(),

0 commit comments

Comments
 (0)