Galaxy Rush Fairness
Galaxy Rush operates on a randomly generated trading algorithm that runs for 24 hours. After each 24-hour trading round, we’ll publish the seed below for anyone to verify. The published seed verifies that we did not alter any prices during the 24-hour round.
Galaxy Rush
- Date & TimeSep 29 2023, 00:00:00Ticks172920Seed3d4f3822cd77c8d5a61f51128515db1c6a79bc22707b08182075330923ea57c3
- Date & TimeSep 28 2023, 00:00:00Ticks172924Seeda1822800cba91d6b61bc39d94704768514d9304c4a559f7f4df921f3df0e4605
- Date & TimeSep 27 2023, 00:00:00Ticks172924Seedcaac9f00b5c905cf834dc2976d13ef8a73fa8ee8f54d4eaa6948aa5e03580006
- Date & TimeSep 26 2023, 00:00:00Ticks172867Seeda9a9a126370439fa884306968356e0a6fdef36323abf1bfa531890637c033737
- Date & TimeSep 25 2023, 00:00:00Ticks172925Seed4167e4f1591d2979c3ff1068ee3d4720abc194837592b4afb6919e379b832e3b
- Date & TimeSep 24 2023, 00:00:00Ticks172930Seed103f55339089ff0b504171df4fd48b99dd907b6823efcc7ae75fe8da39db6b2a
- Date & TimeSep 23 2023, 00:00:00Ticks172916Seed85e6e48782f3139bfd136ff6c9512cdf1c05fd4d4635dd97513976644a481e57
- Date & TimeSep 22 2023, 00:00:00Ticks172915Seed247ddff5b6378f96cb34879415f98eee90449de8868a3ba3d64bcd45fa0172a4
- Date & TimeSep 21 2023, 00:00:00Ticks172917Seede18a302b379eb1c57bfdd80572758f41fc4f83c32e595af94b89b6c946963309
- Date & TimeSep 20 2023, 00:00:00Ticks172921Seedea0ef8569e939fb8c0238859c6f43cf8c5f94a61985a01ffaf443b15d77d308a
Each trading round begins at 00:00 UTC. We randomly generate a new 32-byte seed at the beginning of each round. To reproduce the price movements for a round, combine the seed with an integer tick counter that starts from “0”.
We first encode the seed into a 64-character lowercase hexadecimal string, then we concatenated this with the string representation of the current value of the tick counter. Next, we calculate a hash of the combined string using the BLAKE2b hash function with a digest size of 256 bits. To make sure the price changes are randomized and unpredictable, we use a cryptographic hash function. After a round ends, however, anyone can fully reproduce the round’s price movement using the provided seed.
The first 8 bytes of the hash are converted to an unsigned 64-bit integer assuming a little-endian encoding. This integer value is then converted to a floating point number in the unit range, which will be uniformly distributed. Using the inverse cumulative distribution function with the market’s configured tick volatility (0.1%) as its standard deviation, we then convert the floating point value to a normally distributed return and use that to update the market’s price.
Algorithm
Each trading round begins at 00:00 UTC. We randomly generate a new 32-byte seed at the beginning of each round. To reproduce the price movements for a round, combine the seed with an integer tick counter that starts from “0”.
We first encode the seed into a 64-character lowercase hexadecimal string, then we concatenated this with the string representation of the current value of the tick counter. Next, we calculate a hash of the combined string using the BLAKE2b hash function with a digest size of 256 bits. To make sure the price changes are randomized and unpredictable, we use a cryptographic hash function. After a round ends, however, anyone can fully reproduce the round’s price movement using the provided seed.
The first 8 bytes of the hash are converted to an unsigned 64-bit integer assuming a little-endian encoding. This integer value is then converted to a floating point number in the unit range, which will be uniformly distributed. Using the inverse cumulative distribution function with the market’s configured tick volatility (0.1%) as its standard deviation, we then convert the floating point value to a normally distributed return and use that to update the market’s price.
Verification Example
Anyone can verify the price from a trading round after the seed has been revealed. For example, the following Typescript code calculates the first 5 prices of a round given its seed:
import BigNumber from "bignumber.js";
import blake2b from "blake2b";
import gaussian from "gaussian";
let price = 1000.0;
let seed = "d01dbcc786bdabd07cdd677e04664cbce764ad5fb0a398b4cfcac12aac82f0a6";
let volatility = 0.001;
console.log(`Price[0]: ${price}`);
for (let i = 0; i < 4; i++) {
let combinedValue = Buffer.from(seed + i, "ascii"); // bytes(seed + str(tick), encoding='ascii')
let hash = blake2b(32).update(combinedValue).digest("binary");
let bufferSlice = Buffer.from(hash.slice(0, 8).reverse());
let unsignedIntValue = new BigNumber(`0x${bufferSlice.toString("hex")}`).toNumber();
let unitRangeNumber = unsignedIntValue / (2 ** 64 - 1);
let normalDist = gaussian(0.0, volatility * volatility).ppf(unitRangeNumber);
price = price * (1.0 + normalDist);
console.log(`Price[${i + 1}]: ${price}`);
}
The output should be:
Price[0]: 1000
Price[1]: 999.3340691873984
Price[2]: 999.1870918846727
Price[3]: 1000.0595361633143
Price[4]: 997.9548193056464