Skip to content

Commit

Permalink
Add simple v2 straw
Browse files Browse the repository at this point in the history
  • Loading branch information
erokhinav committed Oct 9, 2024
1 parent 6e154c6 commit e2da312
Show file tree
Hide file tree
Showing 3 changed files with 173 additions and 25 deletions.
115 changes: 115 additions & 0 deletions pkg/bath/stonfi.go
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,121 @@ var StonfiSwapStraw = Straw[BubbleJettonSwap]{
},
}

var StonfiV2PTONStraw = Straw[BubbleJettonTransfer]{
CheckFuncs: []bubbleCheck{IsTx, HasInterface(abi.JettonWallet), HasOperation(abi.JettonTransferMsgOp)},
Builder: func(newAction *BubbleJettonTransfer, bubble *Bubble) error {
tx := bubble.Info.(BubbleTx)
newAction.master, _ = tx.additionalInfo.JettonMaster(tx.account.Address)
newAction.senderWallet = tx.account.Address
newAction.sender = tx.inputFrom
body := tx.decodedBody.Value.(abi.JettonTransferMsgBody)
newAction.amount = body.Amount
newAction.isWrappedTon = true
recipient, err := ton.AccountIDFromTlb(body.Destination)
if err == nil {
newAction.recipient = &Account{Address: *recipient}
}
return nil
},
SingleChild: &Straw[BubbleJettonTransfer]{
CheckFuncs: []bubbleCheck{IsTx, HasOperation(abi.JettonNotifyMsgOp)},
Builder: func(newAction *BubbleJettonTransfer, bubble *Bubble) error {
tx := bubble.Info.(BubbleTx)
newAction.success = true
body := tx.decodedBody.Value.(abi.JettonNotifyMsgBody)
newAction.amount = body.Amount
newAction.payload = body.ForwardPayload.Value
newAction.recipient = &tx.account
return nil
},
},
}

var StonfiSwapV2Straw = Straw[BubbleJettonSwap]{
CheckFuncs: []bubbleCheck{func(bubble *Bubble) bool {
jettonTx, ok := bubble.Info.(BubbleJettonTransfer)
if !ok {
return false
}
if jettonTx.sender == nil {
return false
}
if jettonTx.payload.SumType != abi.StonfiSwapV2JettonOp {
return false
}
swap, ok := jettonTx.payload.Value.(abi.StonfiSwapV2JettonPayload)
if !ok {
return false
}
to, err := ton.AccountIDFromTlb(swap.CrossSwapBody.Receiver)
if err != nil || to == nil {
return false
}
if jettonTx.sender.Address != *to { //protection against invalid swaps
return false
}
return true
}},
Builder: func(newAction *BubbleJettonSwap, bubble *Bubble) error {
newAction.Dex = Stonfi
jettonTx := bubble.Info.(BubbleJettonTransfer)
newAction.UserWallet = jettonTx.sender.Address
newAction.In.Amount = big.Int(jettonTx.amount)
newAction.In.IsTon = jettonTx.isWrappedTon
newAction.In.JettonMaster = jettonTx.master
return nil
},
SingleChild: &Straw[BubbleJettonSwap]{
CheckFuncs: []bubbleCheck{IsTx, HasOperation(abi.StonfiSwapV2MsgOp), HasInterface(abi.StonfiPoolV2)},
Builder: func(newAction *BubbleJettonSwap, bubble *Bubble) error {
tx := bubble.Info.(BubbleTx)
a, b := tx.additionalInfo.STONfiPool.Token0, tx.additionalInfo.STONfiPool.Token1
body := tx.decodedBody.Value.(abi.StonfiSwapV2MsgBody)
if body.QueryId > 0 && a.IsZero() && b.IsZero() {
return nil
}
//newAction.Out.Amount = big.Int(body.MinOut)
//s, err := tongo.AccountIDFromTlb(body.SenderAddress)
//if err != nil {
// return err
//}
//if s != nil && *s == b {
// a, b = b, a
//}
//newAction.In.JettonWallet = a
//newAction.Out.JettonWallet = b
//if tx.additionalInfo != nil {
// newAction.In.JettonMaster, _ = tx.additionalInfo.JettonMaster(a)
// newAction.Out.JettonMaster, _ = tx.additionalInfo.JettonMaster(b)
//}
return nil
},
SingleChild: &Straw[BubbleJettonSwap]{
CheckFuncs: []bubbleCheck{IsTx, HasOperation(abi.StonfiPayToV2MsgOp)},
Builder: func(newAction *BubbleJettonSwap, bubble *Bubble) error {
tx := bubble.Info.(BubbleTx)
newAction.Router = tx.account.Address
return nil
},
SingleChild: &Straw[BubbleJettonSwap]{
CheckFuncs: []bubbleCheck{Is(BubbleJettonTransfer{})},
Builder: func(newAction *BubbleJettonSwap, bubble *Bubble) error {
jettonTx := bubble.Info.(BubbleJettonTransfer)
if jettonTx.senderWallet != newAction.Out.JettonWallet {
// operation has failed,
// stonfi's sent jettons back to the user
return nil
}
newAction.Out.Amount = big.Int(jettonTx.amount)
newAction.Out.IsTon = jettonTx.isWrappedTon
newAction.Success = true
return nil
},
},
},
},
}

// https://dev.tonviewer.com/transaction/e19381edd8f05922eeba3c31f4b8b4b737478b4ca7b37130bdbbfd7bfa773227
// todo: add liquidity (mint lp tokens)
var StonfiMintStraw = Straw[BubbleJettonMint]{}
19 changes: 17 additions & 2 deletions pkg/core/trace.go
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,18 @@ type STONfiPool struct {
Token1 tongo.AccountID
}

type STONfiVersion string

const (
STONfiPoolV1 STONfiVersion = "v1"
STONfiPoolV2 STONfiVersion = "v2"
)

type STONfiPoolID struct {
ID tongo.AccountID
Version STONfiVersion
}

// InformationSource provides methods to construct TraceAdditionalInfo.
type InformationSource interface {
JettonMastersForWallets(ctx context.Context, wallets []tongo.AccountID) (map[tongo.AccountID]tongo.AccountID, error)
Expand Down Expand Up @@ -151,7 +163,7 @@ func CollectAdditionalInfo(ctx context.Context, infoSource InformationSource, tr
}
var jettonWallets []tongo.AccountID
var saleContracts []tongo.AccountID
var stonfiPoolIDs []tongo.AccountID
var stonfiPoolIDs []STONfiPoolID
Visit(trace, func(trace *Trace) {
// when we emulate a trace,
// we construct "trace.AdditionalInfo" in emulatedTreeToTrace for all accounts the trace touches.
Expand All @@ -169,7 +181,10 @@ func CollectAdditionalInfo(ctx context.Context, infoSource InformationSource, tr
saleContracts = append(saleContracts, trace.Account)
}
if hasInterface(trace.AccountInterfaces, abi.StonfiPool) {
stonfiPoolIDs = append(stonfiPoolIDs, trace.Account)
stonfiPoolIDs = append(stonfiPoolIDs, STONfiPoolID{ID: trace.Account, Version: STONfiPoolV1})
}
if hasInterface(trace.AccountInterfaces, abi.StonfiPoolV2) {
stonfiPoolIDs = append(stonfiPoolIDs, STONfiPoolID{ID: trace.Account, Version: STONfiPoolV2})
}
})
stonfiPools, err := infoSource.STONfiPools(ctx, stonfiPoolIDs)

Check failure on line 190 in pkg/core/trace.go

View workflow job for this annotation

GitHub Actions / unit-tests

cannot use stonfiPoolIDs (variable of type []STONfiPoolID) as []ton.AccountID value in argument to infoSource.STONfiPools
Expand Down
64 changes: 41 additions & 23 deletions pkg/litestorage/stonfi.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,34 +8,52 @@ import (
"github.com/tonkeeper/tongo/abi"
)

func (s *LiteStorage) STONfiPools(ctx context.Context, poolIDs []tongo.AccountID) (map[tongo.AccountID]core.STONfiPool, error) {
func (s *LiteStorage) STONfiPools(ctx context.Context, poolIDs []core.STONfiPoolID) (map[tongo.AccountID]core.STONfiPool, error) {
pools := make(map[tongo.AccountID]core.STONfiPool)
for _, poolID := range poolIDs {
_, value, err := abi.GetPoolData(ctx, s.executor, poolID)
_, value, err := abi.GetPoolData(ctx, s.executor, poolID.ID)
if err != nil {
return nil, err
}
result, ok := value.(abi.GetPoolData_StonfiResult)
if !ok {
continue
}
token0, err := tongo.AccountIDFromTlb(result.Token0Address)
if err != nil {
return nil, err
}
if token0 == nil {
continue
}
token1, err := tongo.AccountIDFromTlb(result.Token1Address)
if err != nil {
return nil, err
}
if token1 == nil {
continue
}
pools[poolID] = core.STONfiPool{
Token0: *token0,
Token1: *token1,
switch result := value.(type) {
case abi.GetPoolData_StonfiResult:
token0, err := tongo.AccountIDFromTlb(result.Token0Address)
if err != nil {
return nil, err
}
if token0 == nil {
continue
}
token1, err := tongo.AccountIDFromTlb(result.Token1Address)
if err != nil {
return nil, err
}
if token1 == nil {
continue
}
pools[poolID.ID] = core.STONfiPool{
Token0: *token0,
Token1: *token1,
}
case abi.GetPoolData_StonfiV2Result:
token0, err := tongo.AccountIDFromTlb(result.Token0WalletAddress)
if err != nil {
return nil, err
}
if token0 == nil {
continue
}
token1, err := tongo.AccountIDFromTlb(result.Token1WalletAddress)
if err != nil {
return nil, err
}
if token1 == nil {
continue
}
pools[poolID.ID] = core.STONfiPool{
Token0: *token0,
Token1: *token1,
}
}
}
return pools, nil
Expand Down

0 comments on commit e2da312

Please sign in to comment.