Skip to content

Commit

Permalink
Develop support superposition more (#2685)
Browse files Browse the repository at this point in the history
* New shape for AMM

* Do a lookup to restore the functionality with the amm delta
  • Loading branch information
af-afk authored Sep 4, 2024
1 parent 76dc7c7 commit 07d62d3
Show file tree
Hide file tree
Showing 6 changed files with 196 additions and 6 deletions.
43 changes: 39 additions & 4 deletions cmd/microservice-ethereum-track-amm-positions/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,29 +5,52 @@
package main

import (
"github.com/fluidity-money/fluidity-app/common/ethereum"
"github.com/fluidity-money/fluidity-app/common/ethereum/amm"
"github.com/fluidity-money/fluidity-app/lib/log"
"github.com/fluidity-money/fluidity-app/lib/queue"
ammQueue "github.com/fluidity-money/fluidity-app/lib/queues/amm"
ethQueue "github.com/fluidity-money/fluidity-app/lib/queues/ethereum"
ethTypes "github.com/fluidity-money/fluidity-app/lib/types/ethereum"
"github.com/fluidity-money/fluidity-app/lib/util"
ammTimescale "github.com/fluidity-money/fluidity-app/lib/databases/timescale/amm"

"github.com/fluidity-money/fluidity-app/common/ethereum"
"github.com/fluidity-money/fluidity-app/common/ethereum/amm"
ethLongtail "github.com/fluidity-money/fluidity-app/common/ethereum/longtail"

"github.com/ethereum/go-ethereum/ethclient"
)

const (
// EnvAmmAddress to track events emitted by the AMM
EnvAmmAddress = `FLU_ETHEREUM_AMM_ADDRESS`

// EnvEthereumHttpUrl is the url to use to connect to the HTTP Geth endpoint for delta
// lookups
EnvEthereumHttpUrl = `FLU_ETHEREUM_HTTP_URL`
)

func main() {
var (
ammAddress_ = util.GetEnvOrFatal(EnvAmmAddress)
gethHttpUrl = util.PickEnvOrFatal(EnvEthereumHttpUrl)
)

ethClient, err := ethclient.Dial(gethHttpUrl)

if err != nil {
log.Fatal(func(k *log.Log) {
k.Message = "Failed to connect to Geth Websocket!"
k.Payload = err
})
}

defer ethClient.Close()

ammAddress := ethTypes.AddressFromString(ammAddress_)

ethQueue.Logs(func(log_ ethQueue.Log) {
log.Debugf("got a log: %v", log_)

if log_.Address != ammAddress {
return
}
Expand All @@ -49,7 +72,7 @@ func main() {
case amm.AmmAbi.Events["MintPosition"].ID:
handleMint(log_)
case amm.AmmAbi.Events["UpdatePositionLiquidity"].ID:
handleUpdate(log_)
handleUpdate(ethClient, ammAddress, log_)
default:
// swaps are handled in microservice-eth-user-actions and in the apps server
log.App(func(k *log.Log) {
Expand All @@ -75,7 +98,7 @@ func handleMint(log_ ethQueue.Log) {
queue.SendMessage(ammQueue.TopicPositionMint, mint)
}

func handleUpdate(log_ ethQueue.Log) {
func handleUpdate(client *ethclient.Client, ammAddress ethTypes.Address, log_ ethQueue.Log) {
update, err := amm.DecodeUpdatePosition(log_)

if err != nil {
Expand All @@ -85,5 +108,17 @@ func handleUpdate(log_ ethQueue.Log) {
})
}

// get the pool associated with this position

positionId := update.Id

pool := ammTimescale.GetPositionPool(positionId)

// get the delta so we can use it later in the database

delta := ethLongtail.GetPositionLiquidity(client, ammAddress, pool, positionId)

update.Delta = delta

queue.SendMessage(ammQueue.TopicPositionUpdate, update)
}
4 changes: 4 additions & 0 deletions common/ethereum/amm/abi.go
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,10 @@ type (
Id misc.BigInt `json:"id"`
Token0 misc.BigInt `json:"token0"`
Token1 misc.BigInt `json:"token1"`

// Delta is needed by the AMM positions microservice so we can calculate who
// receives rewards. So this is added by the microservice that unpacks this data.
Delta misc.BigInt `json:"delta"`
}
AmmEventCollectFees struct {
Id misc.BigInt
Expand Down
26 changes: 26 additions & 0 deletions common/ethereum/longtail/abi.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
[
{
"type": "function",
"name": "positionLiquidity8D11C045",
"inputs": [
{
"name": "pool",
"type": "address",
"internalType": "address"
},
{
"name": "id",
"type": "uint256",
"internalType": "uint256"
}
],
"outputs": [
{
"name": "",
"type": "uint128",
"internalType": "uint128"
}
],
"stateMutability": "nonpayable"
}
]
21 changes: 21 additions & 0 deletions common/ethereum/longtail/init.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
// Copyright 2022 Fluidity Money. All rights reserved. Use of this
// source code is governed by a GPL-style license that can be found in the
// LICENSE.md file.

package longtail

import (
"bytes"

ethAbi "github.com/ethereum/go-ethereum/accounts/abi"
)

func init() {
longtailReader := bytes.NewBuffer(longtailBytes)

var err error

if longtailAbi, err = ethAbi.JSON(longtailReader); err != nil {
panic(err)
}
}
79 changes: 79 additions & 0 deletions common/ethereum/longtail/longtail.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
// Copyright 2022 Fluidity Money. All rights reserved. Use of this
// source code is governed by a GPL-style license that can be found in the
// LICENSE.md file.

package longtail

import (
_ "embed"
"math/big"

"github.com/fluidity-money/fluidity-app/common/ethereum"
"github.com/fluidity-money/fluidity-app/lib/log"
"github.com/fluidity-money/fluidity-app/lib/types/misc"
libEth "github.com/fluidity-money/fluidity-app/lib/types/ethereum"

ethAbi "github.com/ethereum/go-ethereum/accounts/abi"
ethCommon "github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/ethclient"
)

// Context for logging
const Context = "LONGTAIL"

//go:embed abi.json
var longtailBytes []byte

var longtailAbi ethAbi.ABI

// GetPositionLiquidity for a pool and position ID given
func GetPositionLiquidity(client *ethclient.Client, amm_, pool_ libEth.Address, id misc.BigInt) misc.BigInt {
var (
amm = ethCommon.HexToAddress(amm_.String())
pool = ethCommon.HexToAddress(pool_.String())
)
log.Debug(func(k *log.Log) {
k.Context = Context

k.Format(
"Using the Longtail AMM pool %v to get a position's liquidity",
pool,
)

k.Payload = id
})

resp, err := ethereum.StaticCall(
client,
amm,
longtailAbi,
"positionLiquidity8D11C045",
pool,
id,
)

if err != nil {
log.Fatal(func(k *log.Log) {
k.Context = Context

k.Format(
"Failed to do a static call to positionLiquidity8D11C045! Pool address %v, id %v",
pool,
id,
)

k.Payload = err
})
}

liquidity, ok := resp[0].(*big.Int)

if !ok {
log.Fatal(func(k *log.Log) {
k.Context = Context
k.Format("Incorrect position liquidity type %T", resp[0])
})
}

return misc.NewBigIntFromInt(*liquidity)
}
29 changes: 27 additions & 2 deletions lib/databases/timescale/amm/amm.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,17 @@ import (
"fmt"
"math/big"

"github.com/fluidity-money/fluidity-app/common/ethereum/amm"
"github.com/fluidity-money/fluidity-app/lib/log"
"github.com/fluidity-money/fluidity-app/lib/timescale"
"github.com/fluidity-money/fluidity-app/lib/types/applications"
"github.com/fluidity-money/fluidity-app/lib/types/ethereum"
"github.com/fluidity-money/fluidity-app/lib/types/misc"
"github.com/fluidity-money/fluidity-app/lib/types/network"
token_details "github.com/fluidity-money/fluidity-app/lib/types/token-details"
"github.com/fluidity-money/fluidity-app/lib/types/worker"
"github.com/fluidity-money/fluidity-app/lib/types/ethereum"


"github.com/fluidity-money/fluidity-app/common/ethereum/amm"
)

const (
Expand Down Expand Up @@ -78,6 +80,29 @@ func InsertAmmPosition(mint amm.AmmEventPositionMint) {
}
}

func GetPositionPool(id misc.BigInt) (pool ethereum.Address) {
timescaleClient := timescale.Client()

statementText := fmt.Sprintf(
`SELECT pool_address FROM %v WHERE position_id = $1`,
TableAmmPositions,
)

row := timescaleClient.QueryRow(statementText, id)

err := row.Scan(&pool)

if err != nil {
log.Fatal(func(k *log.Log) {
k.Context = Context
k.Message = "Failed to update a position's liquidity!"
k.Payload = err
})
}

return pool
}

func UpdateAmmPosition(update amm.AmmEventPositionUpdate) {
timescaleClient := timescale.Client()

Expand Down

0 comments on commit 07d62d3

Please sign in to comment.