192 lines
5.2 KiB
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
|
|
}
|