Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Deploy things #106

Merged
merged 8 commits into from
Sep 4, 2023
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
16 changes: 10 additions & 6 deletions plugin/evm/limit_order.go
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ func NewLimitOrderProcesser(ctx *snow.Context, txPool *txpool.TxPool, shutdownCh

// need to register the types for gob encoding because memory DB has an interface field(ContractOrder)
gob.Register(&orderbook.LimitOrder{})
gob.Register(&orderbook.LimitOrderV2{})
gob.Register(&orderbook.IOCOrder{})
return &limitOrderProcesser{
ctx: ctx,
Expand Down Expand Up @@ -231,14 +232,17 @@ func (lop *limitOrderProcesser) listenAndStoreLimitOrderTransactions() {
// If n is the block at which snapshot should be saved(n is multiple of [snapshotInterval]), save the snapshot
// when logs of block number >= n + 1 are received before applying them in memory db

blockNumberFloor := ((blockNumber - 1) / snapshotInterval) * snapshotInterval
// snapshot should be saved at block number = blockNumber - 1 because Accepted logs
// have been applied in memory DB at this point
snapshotBlockNumber := blockNumber - 1
blockNumberFloor := ((snapshotBlockNumber) / snapshotInterval) * snapshotInterval
if blockNumberFloor > lop.snapshotSavedBlockNumber {
log.Info("Saving memory DB snapshot", "blockNumber", blockNumber, "blockNumberFloor", blockNumberFloor)
floorBlock := lop.blockChain.GetBlockByNumber(blockNumberFloor)
lop.memoryDb.Accept(blockNumberFloor, floorBlock.Timestamp())
err := lop.saveMemoryDBSnapshot(big.NewInt(int64(blockNumberFloor)))
log.Info("Saving memory DB snapshot", "snapshotBlockNumber", snapshotBlockNumber, "current blockNumber", blockNumber, "blockNumberFloor", blockNumberFloor)
snapshotBlock := lop.blockChain.GetBlockByNumber(snapshotBlockNumber)
lop.memoryDb.Accept(snapshotBlockNumber, snapshotBlock.Timestamp())
err := lop.saveMemoryDBSnapshot(big.NewInt(int64(snapshotBlockNumber)))
if err != nil {
log.Error("Error in saving memory DB snapshot", "err", err)
log.Error("Error in saving memory DB snapshot", "err", err, "snapshotBlockNumber", snapshotBlockNumber, "current blockNumber", blockNumber, "blockNumberFloor", blockNumberFloor)
}
}

Expand Down
23 changes: 19 additions & 4 deletions plugin/evm/orderbook/memory_database.go
Original file line number Diff line number Diff line change
Expand Up @@ -264,6 +264,8 @@ func (db *InMemoryDatabase) LoadFromSnapshot(snapshot Snapshot) error {
db.TraderMap = snapshot.Data.TraderMap
db.LastPrice = snapshot.Data.LastPrice
db.NextFundingTime = snapshot.Data.NextFundingTime
db.NextSamplePITime = snapshot.Data.NextSamplePITime
db.CumulativePremiumFraction = snapshot.Data.CumulativePremiumFraction

return nil
}
Expand Down Expand Up @@ -753,7 +755,8 @@ func (db *InMemoryDatabase) GetNaughtyTraders(oraclePrices map[Market]*big.Int,
}
// has orders that might be cancellable
availableMargin := getAvailableMargin(trader, pendingFunding, oraclePrices, db.LastPrice, db.configService.getMinAllowableMargin(), markets)
if availableMargin.Cmp(big.NewInt(0)) == -1 {
// availableMargin := getAvailableMarginWithDebugInfo(addr, trader, pendingFunding, oraclePrices, db.LastPrice, db.configService.getMinAllowableMargin(), markets)
if availableMargin.Sign() == -1 {
foundCancellableOrders := db.determineOrdersToCancel(addr, trader, availableMargin, oraclePrices, ordersToCancel)
if foundCancellableOrders {
log.Info("negative available margin", "trader", addr.String(), "availableMargin", prettifyScaledBigInt(availableMargin, 6))
Expand Down Expand Up @@ -929,18 +932,30 @@ func getBlankTrader() *Trader {
}

func getAvailableMargin(trader *Trader, pendingFunding *big.Int, oraclePrices map[Market]*big.Int, lastPrices map[Market]*big.Int, minAllowableMargin *big.Int, markets []Market) *big.Int {
// log.Info("in getAvailableMargin", "trader", trader, "pendingFunding", pendingFunding, "oraclePrices", oraclePrices, "lastPrices", lastPrices)
margin := new(big.Int).Sub(getNormalisedMargin(trader), pendingFunding)
notionalPosition, unrealizePnL := getTotalNotionalPositionAndUnrealizedPnl(trader, margin, Min_Allowable_Margin, oraclePrices, lastPrices, markets)
utilisedMargin := divideByBasePrecision(new(big.Int).Mul(notionalPosition, minAllowableMargin))
// print margin, notionalPosition, unrealizePnL, utilisedMargin
// log.Info("stats", "margin", margin, "notionalPosition", notionalPosition, "unrealizePnL", unrealizePnL, "utilisedMargin", utilisedMargin, "Reserved", trader.Margin.Reserved)
return new(big.Int).Sub(
new(big.Int).Add(margin, unrealizePnL),
new(big.Int).Add(utilisedMargin, trader.Margin.Reserved),
)
}

func getAvailableMarginWithDebugInfo(addr common.Address, trader *Trader, pendingFunding *big.Int, oraclePrices map[Market]*big.Int, lastPrices map[Market]*big.Int, minAllowableMargin *big.Int, markets []Market) *big.Int {
margin := new(big.Int).Sub(getNormalisedMargin(trader), pendingFunding)
notionalPosition, unrealizePnL := getTotalNotionalPositionAndUnrealizedPnl(trader, margin, Min_Allowable_Margin, oraclePrices, lastPrices, markets)
utilisedMargin := divideByBasePrecision(new(big.Int).Mul(notionalPosition, minAllowableMargin))
availableMargin := new(big.Int).Sub(
new(big.Int).Add(margin, unrealizePnL),
new(big.Int).Add(utilisedMargin, trader.Margin.Reserved),
)
if availableMargin.Sign() == -1 {
log.Info("availableMargin < 0", "addr", addr.String(), "pendingFunding", pendingFunding, "margin", margin, "notionalPosition", notionalPosition, "unrealizePnL", unrealizePnL, "utilisedMargin", utilisedMargin, "Reserved", trader.Margin.Reserved)
log.Info("prices", "oraclePrices", oraclePrices, "lastPrices", lastPrices)
}
return availableMargin
}

// deepCopyOrder deep copies the LimitOrder struct
func deepCopyOrder(order *Order) Order {
lifecycleList := &order.LifecycleList
Expand Down
4 changes: 2 additions & 2 deletions plugin/evm/orderbook/tx_processor.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ package orderbook
import (
"context"
"crypto/ecdsa"
"encoding/hex"
// "encoding/hex"
"errors"
"fmt"
"math/big"
Expand Down Expand Up @@ -139,7 +139,7 @@ func (lotp *limitOrderTxProcessor) ExecuteMatchedOrdersTx(longOrder Order, short
return err
}

log.Info("ExecuteMatchedOrdersTx", "orders[0]", hex.EncodeToString(orders[0]), "orders[1]", hex.EncodeToString(orders[1]), "fillAmount", prettifyScaledBigInt(fillAmount, 18))
// log.Info("ExecuteMatchedOrdersTx", "orders[0]", hex.EncodeToString(orders[0]), "orders[1]", hex.EncodeToString(orders[1]), "fillAmount", prettifyScaledBigInt(fillAmount, 18))
txHash, err := lotp.executeLocalTx(lotp.orderBookContractAddress, lotp.orderBookABI, "executeMatchedOrders", orders, fillAmount)
log.Info("ExecuteMatchedOrdersTx", "LongOrder", longOrder, "ShortOrder", shortOrder, "fillAmount", prettifyScaledBigInt(fillAmount, 18), "txHash", txHash.String(), "err", err)
return err
Expand Down
5 changes: 3 additions & 2 deletions precompile/contracts/bibliophile/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package bibliophile

import (
"math/big"
"time"

"github.com/ava-labs/subnet-evm/precompile/contract"
"github.com/ethereum/go-ethereum/common"
Expand All @@ -28,7 +29,7 @@ func GetClearingHouseVariables(stateDB contract.StateDB, trader common.Address)
Trader: trader,
IncludeFundingPayments: false,
Mode: 0,
}, big.NewInt(0))
}, big.NewInt(time.Now().Unix()))
totalFunding := GetTotalFunding(stateDB, &trader)
positionSizes := getPosSizes(stateDB, &trader)
underlyingPrices := GetUnderlyingPrices(stateDB)
Expand Down Expand Up @@ -118,7 +119,7 @@ func GetAMMVariables(stateDB contract.StateDB, ammAddress common.Address, ammInd
minAllowableMargin := GetMinAllowableMargin(stateDB)
takerFee := GetTakerFee(stateDB)
totalMargin := GetNormalizedMargin(stateDB, trader)
availableMargin := GetAvailableMargin(stateDB, trader)
availableMargin := GetAvailableMargin(stateDB, trader, big.NewInt(time.Now().Unix()))
reduceOnlyAmount := getReduceOnlyAmount(stateDB, trader, big.NewInt(ammIndex))
longOpenOrdersAmount := getLongOpenOrdersAmount(stateDB, trader, big.NewInt(ammIndex))
shortOpenOrdersAmount := getShortOpenOrdersAmount(stateDB, trader, big.NewInt(ammIndex))
Expand Down
8 changes: 7 additions & 1 deletion precompile/contracts/bibliophile/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ type BibliophileClient interface {
GetShortOpenOrdersAmount(trader common.Address, ammIndex *big.Int) *big.Int
GetReduceOnlyAmount(trader common.Address, ammIndex *big.Int) *big.Int
IsTradingAuthority(trader, senderOrSigner common.Address) bool
IsValidator(senderOrSigner common.Address) bool
// Limit Order
GetBlockPlaced(orderHash [32]byte) *big.Int
GetOrderFilledAmount(orderHash [32]byte) *big.Int
Expand Down Expand Up @@ -118,6 +119,10 @@ func (b *bibliophileClient) IsTradingAuthority(trader, senderOrSigner common.Add
return IsTradingAuthority(b.accessibleState.GetStateDB(), trader, senderOrSigner)
}

func (b *bibliophileClient) IsValidator(senderOrSigner common.Address) bool {
return IsValidator(b.accessibleState.GetStateDB(), senderOrSigner)
}

func (b *bibliophileClient) IOC_GetExpirationCap() *big.Int {
return iocGetExpirationCap(b.accessibleState.GetStateDB())
}
Expand Down Expand Up @@ -171,5 +176,6 @@ func (b *bibliophileClient) GetReduceOnlyAmount(trader common.Address, ammIndex
}

func (b *bibliophileClient) GetAvailableMargin(trader common.Address) *big.Int {
return GetAvailableMargin(b.accessibleState.GetStateDB(), trader)
blockTimestamp := new(big.Int).SetUint64(b.accessibleState.GetBlockContext().Timestamp())
return GetAvailableMargin(b.accessibleState.GetStateDB(), trader, blockTimestamp)
}
22 changes: 18 additions & 4 deletions precompile/contracts/bibliophile/client_mock.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

14 changes: 12 additions & 2 deletions precompile/contracts/bibliophile/margin_account.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (

"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/crypto"
// "github.com/ethereum/go-ethereum/log"
)

const (
Expand All @@ -32,13 +33,22 @@ func getReservedMargin(stateDB contract.StateDB, trader common.Address) *big.Int
return stateDB.GetState(common.HexToAddress(MARGIN_ACCOUNT_GENESIS_ADDRESS), common.BytesToHash(baseMappingHash)).Big()
}

func GetAvailableMargin(stateDB contract.StateDB, trader common.Address) *big.Int {
// Monday, 4 September 2023 10:05:00
var V5ActivationDate *big.Int = new(big.Int).SetInt64(1693821900)

func GetAvailableMargin(stateDB contract.StateDB, trader common.Address, blockTimestamp *big.Int) *big.Int {
includeFundingPayment := true
mode := uint8(1) // Min_Allowable_Margin
output := GetNotionalPositionAndMargin(stateDB, &GetNotionalPositionAndMarginInput{Trader: trader, IncludeFundingPayments: includeFundingPayment, Mode: mode}, nil)
var output GetNotionalPositionAndMarginOutput
if blockTimestamp != nil && blockTimestamp.Cmp(V5ActivationDate) == 1 {
output = GetNotionalPositionAndMargin(stateDB, &GetNotionalPositionAndMarginInput{Trader: trader, IncludeFundingPayments: includeFundingPayment, Mode: mode}, blockTimestamp)
} else {
output = GetNotionalPositionAndMargin(stateDB, &GetNotionalPositionAndMarginInput{Trader: trader, IncludeFundingPayments: includeFundingPayment, Mode: mode}, nil)
}
notionalPostion := output.NotionalPosition
margin := output.Margin
utitlizedMargin := divide1e6(big.NewInt(0).Mul(notionalPostion, GetMinAllowableMargin(stateDB)))
reservedMargin := getReservedMargin(stateDB, trader)
// log.Info("GetAvailableMargin", "trader", trader, "notionalPostion", notionalPostion, "margin", margin, "utitlizedMargin", utitlizedMargin, "reservedMargin", reservedMargin)
return big.NewInt(0).Sub(big.NewInt(0).Sub(margin, utitlizedMargin), reservedMargin)
}
6 changes: 6 additions & 0 deletions precompile/contracts/bibliophile/orderbook.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import (
const (
ORDERBOOK_GENESIS_ADDRESS = "0x0300000000000000000000000000000000000000"
ORDER_INFO_SLOT int64 = 53
IS_VALIDATOR_SLOT int64 = 54
REDUCE_ONLY_AMOUNT_SLOT int64 = 55
IS_TRADING_AUTHORITY_SLOT int64 = 61
LONG_OPEN_ORDERS_SLOT int64 = 65
Expand Down Expand Up @@ -79,6 +80,11 @@ func IsTradingAuthority(stateDB contract.StateDB, trader, senderOrSigner common.
return stateDB.GetState(common.HexToAddress(ORDERBOOK_GENESIS_ADDRESS), common.BytesToHash(tradingAuthorityMappingSlot)).Big().Cmp(big.NewInt(1)) == 0
}

func IsValidator(stateDB contract.StateDB, senderOrSigner common.Address) bool {
isValidatorMappingSlot := crypto.Keccak256(append(common.LeftPadBytes(senderOrSigner.Bytes(), 32), common.LeftPadBytes(big.NewInt(IS_VALIDATOR_SLOT).Bytes(), 32)...))
return stateDB.GetState(common.HexToAddress(ORDERBOOK_GENESIS_ADDRESS), common.BytesToHash(isValidatorMappingSlot)).Big().Cmp(big.NewInt(1)) == 0
}

// Business Logic

func ValidateOrdersAndDetermineFillPrice(stateDB contract.StateDB, inputStruct *ValidateOrdersAndDetermineFillPriceInput) (*ValidateOrdersAndDetermineFillPriceOutput, error) {
Expand Down
6 changes: 2 additions & 4 deletions precompile/contracts/juror/contract.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
package juror

import (
"encoding/hex"
"errors"
"fmt"
"math/big"
Expand Down Expand Up @@ -442,7 +441,7 @@ func validateCancelLimitOrder(accessibleState contract.AccessibleState, caller c
}
// CUSTOM CODE STARTS HERE
bibliophile := bibliophile.NewBibliophileClient(accessibleState)
output := ValidateCancelLimitOrderV2(bibliophile, &inputStruct)
output := ValidateCancelLimitOrderV2(bibliophile, &inputStruct, new(big.Int).SetUint64(accessibleState.GetBlockContext().Timestamp()))
packedOutput, err := PackValidateCancelLimitOrderOutput(*output)
if err != nil {
return nil, remainingGas, err
Expand Down Expand Up @@ -541,7 +540,6 @@ func validateOrdersAndDetermineFillPrice(accessibleState contract.AccessibleStat
return nil, remainingGas, err
}

log.Info("validateOrdersAndDetermineFillPrice", "orders[0]", hex.EncodeToString(inputStruct.Data[0]), "orders[1]", hex.EncodeToString(inputStruct.Data[1]), "fillAmount", inputStruct.FillAmount)
// CUSTOM CODE STARTS HERE
bibliophile := bibliophile.NewBibliophileClient(accessibleState)
output, err := ValidateOrdersAndDetermineFillPrice(bibliophile, &inputStruct)
Expand Down Expand Up @@ -625,7 +623,7 @@ func PackValidatePlaceLimitOrder(inputStruct ValidatePlaceLimitOrderInput) ([]by
func PackValidatePlaceLimitOrderOutput(outputStruct ValidatePlaceLimitOrderOutput) ([]byte, error) {
// @todo orderHash looks ugly
// lvl=info msg=validatePlaceLimitOrder outputStruct="{Errs: Orderhash:[163 9 195 151 255 44 17 22 177 218 216 139 75 238 217 56 226 244 244 41 106 243 100 63 204 145 170 96 95 106 252 157] Res:{ReserveAmount:+6015000 Amm:0x8f86403A4DE0BB5791fa46B8e795C547942fE4Cf}}"
log.Info("validatePlaceLimitOrder", "outputStruct", outputStruct)
// log.Info("validatePlaceLimitOrder", "outputStruct", outputStruct)
return JurorABI.PackOutput("validatePlaceLimitOrder",
outputStruct.Errs,
outputStruct.Orderhash,
Expand Down
Loading