sorare/mutations/limit_order.go

192 lines
5.2 KiB
Go

package mutations
import (
"math/big"
"strconv"
"strings"
"github.com/pkg/errors"
"git.lehouerou.net/laurent/sorare/starkware"
)
type LimitOrder struct {
AmountBuy string `json:"amountBuy"`
AmountSell string `json:"amountSell"`
ExpirationTimestamp int `json:"expirationTimestamp"`
FeeInfo *struct {
FeeLimit string `json:"feeLimit"`
SourceVaultId int `json:"sourceVaultId"`
TokenId string `json:"tokenId"`
} `json:"feeInfo"`
Nonce int `json:"nonce"`
TokenBuy string `json:"tokenBuy"`
TokenSell string `json:"tokenSell"`
VaultIdBuy int `json:"vaultIdBuy"`
VaultIdSell int `json:"vaultIdSell"`
}
func (o LimitOrder) hash() (string, error) {
vaultSellBn := big.NewInt(int64(o.VaultIdSell))
vaultBuyBn := big.NewInt(int64(o.VaultIdBuy))
amountSellInt, err := strconv.ParseInt(o.AmountSell, 10, 64)
if err != nil {
return "", errors.Wrap(err, "parsing amountSell")
}
amountSellBn := big.NewInt(amountSellInt)
amountBuyInt, err := strconv.ParseInt(o.AmountBuy, 10, 64)
if err != nil {
return "", errors.Wrap(err, "parsing amountBuy")
}
amountBuyBn := big.NewInt(amountBuyInt)
nonceBn := big.NewInt(int64(o.Nonce))
expirationTimestampBn := big.NewInt(int64(o.ExpirationTimestamp))
tokenSell := o.TokenSell
if strings.HasPrefix(tokenSell, "0x") {
tokenSell = tokenSell[2:]
}
tokenBuy := o.TokenBuy
if strings.HasPrefix(tokenBuy, "0x") {
tokenBuy = tokenBuy[2:]
}
if o.FeeInfo != nil {
feeVaultIdBn := big.NewInt(int64(o.FeeInfo.SourceVaultId))
feeLimitInt, err := strconv.ParseInt(o.FeeInfo.FeeLimit, 10, 64)
if err != nil {
return "", errors.Wrap(err, "parsing feeLimit")
}
feeLimitBn := big.NewInt(feeLimitInt)
feeToken := o.FeeInfo.TokenId
if strings.HasPrefix(feeToken, "0x") {
feeToken = feeToken[2:]
}
return hashLimitOrderWithFee(
big.NewInt(3),
vaultSellBn,
vaultBuyBn,
amountSellBn,
amountBuyBn,
nonceBn,
expirationTimestampBn,
tokenSell,
tokenBuy,
feeToken,
feeVaultIdBn,
feeLimitBn,
)
} else {
return hashLimitOrder(
big.NewInt(0),
vaultSellBn,
vaultBuyBn,
amountSellBn,
amountBuyBn,
nonceBn,
expirationTimestampBn,
tokenSell,
tokenBuy,
)
}
}
func hashLimitOrderWithFee(
instructionType *big.Int,
vaultSell *big.Int,
vaultBuy *big.Int,
amountSell *big.Int,
amountBuy *big.Int,
nonce *big.Int,
expirationTimestamp *big.Int,
tokenSell string,
tokenBuy string,
feeToken string,
feeVaultId *big.Int,
feeLimit *big.Int) (string, error) {
packedMessage1 := big.NewInt(0).Set(amountSell)
packedMessage1.Lsh(packedMessage1, 64)
packedMessage1.Add(packedMessage1, amountBuy)
packedMessage1.Lsh(packedMessage1, 64)
packedMessage1.Add(packedMessage1, feeLimit)
packedMessage1.Lsh(packedMessage1, 32)
packedMessage1.Add(packedMessage1, nonce)
packedMessage2 := big.NewInt(0).Set(instructionType)
packedMessage2.Lsh(packedMessage2, 64)
packedMessage2.Add(packedMessage2, feeVaultId)
packedMessage2.Lsh(packedMessage2, 64)
packedMessage2.Add(packedMessage2, vaultSell)
packedMessage2.Lsh(packedMessage2, 64)
packedMessage2.Add(packedMessage2, vaultBuy)
packedMessage2.Lsh(packedMessage2, 32)
packedMessage2.Add(packedMessage2, expirationTimestamp)
packedMessage2.Lsh(packedMessage2, 17)
packedMessage2.Add(packedMessage2, big.NewInt(0))
tokenSellbn, ok := big.NewInt(0).SetString(tokenSell, 16)
if !ok {
return "", errors.Errorf("token0 is not a hex string: %s", tokenSell)
}
tokenBuybn, ok := big.NewInt(0).SetString(tokenBuy, 16)
if !ok {
return "", errors.Errorf("token1 is not a hex string: %s", tokenBuy)
}
feeTokenbn, ok := big.NewInt(0).SetString(feeToken, 16)
if !ok {
return "", errors.Errorf("feeToken is not a hex string: %s", feeToken)
}
tmpHash := starkware.PedersenHash(
starkware.PedersenHash(tokenSellbn.String(), tokenBuybn.String()),
feeTokenbn.String(),
)
return starkware.PedersenHash(
starkware.PedersenHash(tmpHash, packedMessage1.String()),
packedMessage2.String(),
), nil
}
func hashLimitOrder(
instructionType *big.Int,
vaultSell *big.Int,
vaultBuy *big.Int,
amountSell *big.Int,
amountBuy *big.Int,
nonce *big.Int,
expirationTimestamp *big.Int,
tokenSell string,
tokenBuy string,
) (string, error) {
packedMessage := big.NewInt(0).Set(instructionType)
packedMessage.Lsh(packedMessage, 31)
packedMessage.Add(packedMessage, vaultSell)
packedMessage.Lsh(packedMessage, 31)
packedMessage.Add(packedMessage, vaultBuy)
packedMessage.Lsh(packedMessage, 63)
packedMessage.Add(packedMessage, amountSell)
packedMessage.Lsh(packedMessage, 63)
packedMessage.Add(packedMessage, amountBuy)
packedMessage.Lsh(packedMessage, 31)
packedMessage.Add(packedMessage, nonce)
packedMessage.Lsh(packedMessage, 22)
packedMessage.Add(packedMessage, expirationTimestamp)
tokenSellbn, ok := big.NewInt(0).SetString(tokenSell, 16)
if !ok {
return "", errors.Errorf("tokenSell is not a hex string: %s", tokenSell)
}
tokenBuybn, ok := big.NewInt(0).SetString(tokenBuy, 16)
if !ok {
return "", errors.Errorf("tokenBuy is not a hex string: %s", tokenBuy)
}
return starkware.PedersenHash(
starkware.PedersenHash(tokenSellbn.String(), tokenBuybn.String()),
packedMessage.String(),
), nil
}