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 }