Skip to content

Commit c711d6a

Browse files
committed
server/runtimes: EVM tokens sorting param
1 parent 00eae0f commit c711d6a

File tree

9 files changed

+230
-29
lines changed

9 files changed

+230
-29
lines changed

.changelog/828.feature.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
Add `sort_by` parameter to `/{runtime}/evm_tokens` endpoint.
2+
3+
The parameter can be used to configure if results should be sorted by number
4+
of total holders, or by the calculated market cap.

api/spec/v1.yaml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1082,6 +1082,14 @@ paths:
10821082
schema:
10831083
type: string
10841084
description: A filter on the name, the name or symbol must contain this value as a substring.
1085+
- in: query
1086+
name: sort_by
1087+
schema:
1088+
type: string
1089+
enum: [total_holders, market_cap]
1090+
description: |
1091+
The field to sort the tokens by.
1092+
If unset, the tokens will be sorted by number of holders.
10851093
responses:
10861094
'200':
10871095
description: The requested tokens.

storage/client/client.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2005,6 +2005,7 @@ func (c *StorageClient) RuntimeTokens(ctx context.Context, p apiTypes.GetRuntime
20052005
p.Name,
20062006
refSwapFactoryAddr,
20072007
refSwapTokenAddr,
2008+
p.SortBy,
20082009
p.Limit,
20092010
p.Offset,
20102011
)

storage/client/queries/queries.go

Lines changed: 32 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -704,37 +704,40 @@ const (
704704
tokens.token_type IS NOT NULL AND -- exclude token _candidates_ that we haven't inspected yet
705705
tokens.token_type != 0 -- exclude unknown-type tokens; they're often just contracts that emitted Transfer events but don't expose the token ticker, name, balance etc.
706706
ORDER BY
707-
(
708-
CASE
709-
-- For the reference token itself, it is 1:1 in value with, you know, itself.
710-
WHEN
711-
tokens.token_address = $5
712-
THEN 1.0
713-
-- The pool keeps a proportion of reserves so that reserve0 of token0 is worth about as much as reserve1 of token1.
714-
-- When token0 is the reference token, more reserve0 means token1 is worth more than the reference token.
715-
WHEN
716-
ref_swap_pair_creations.token0_address = $5 AND
717-
ref_swap_pairs.reserve0 IS NOT NULL AND
718-
ref_swap_pairs.reserve0 > 0 AND
719-
ref_swap_pairs.reserve1 IS NOT NULL AND
720-
ref_swap_pairs.reserve1 > 0
721-
THEN ref_swap_pairs.reserve0::REAL / ref_swap_pairs.reserve1::REAL
722-
-- When token1 is the reference token, more reserve1 means token0 is worth more than the reference token.
723-
WHEN
724-
ref_swap_pair_creations.token1_address = $5 AND
725-
ref_swap_pairs.reserve0 IS NOT NULL AND
726-
ref_swap_pairs.reserve0 > 0 AND
727-
ref_swap_pairs.reserve1 IS NOT NULL AND
728-
ref_swap_pairs.reserve1 > 0
729-
THEN ref_swap_pairs.reserve1::REAL / ref_swap_pairs.reserve0::REAL
730-
ELSE 0.0
731-
END *
732-
COALESCE(tokens.total_supply, 0)
733-
) DESC,
707+
CASE
708+
-- If sort_by is not "market_cap" then we sort by num_holders (below).
709+
WHEN $6::text IS NULL OR $6::text != 'market_cap' THEN NULL
710+
ELSE
711+
-- Otherwise, sort by market cap.
712+
(
713+
CASE
714+
-- For the reference token itself, it is 1:1 in value with, you know, itself.
715+
WHEN tokens.token_address = $5 THEN 1.0
716+
-- The pool keeps a proportion of reserves so that reserve0 of token0 is worth about as much as reserve1 of token1.
717+
-- When token0 is the reference token, more reserve0 means token1 is worth more than the reference token.
718+
WHEN
719+
ref_swap_pair_creations.token0_address = $5 AND
720+
ref_swap_pairs.reserve0 IS NOT NULL AND
721+
ref_swap_pairs.reserve0 > 0 AND
722+
ref_swap_pairs.reserve1 IS NOT NULL AND
723+
ref_swap_pairs.reserve1 > 0
724+
THEN ref_swap_pairs.reserve0::REAL / ref_swap_pairs.reserve1::REAL
725+
-- When token1 is the reference token, more reserve1 means token0 is worth more than the reference token.
726+
WHEN
727+
ref_swap_pair_creations.token1_address = $5 AND
728+
ref_swap_pairs.reserve0 IS NOT NULL AND
729+
ref_swap_pairs.reserve0 > 0 AND
730+
ref_swap_pairs.reserve1 IS NOT NULL AND
731+
ref_swap_pairs.reserve1 > 0
732+
THEN ref_swap_pairs.reserve1::REAL / ref_swap_pairs.reserve0::REAL
733+
ELSE 0.0
734+
END * COALESCE(tokens.total_supply, 0)
735+
)
736+
END DESC,
734737
num_holders DESC,
735738
contract_addr
736-
LIMIT $6::bigint
737-
OFFSET $7::bigint`
739+
LIMIT $7::bigint
740+
OFFSET $8::bigint`
738741

739742
//nolint:gosec // Linter suspects a hardcoded credentials token.
740743
EvmTokenHolders = `

tests/e2e_regression/common_test_cases.sh

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@ commonTestCases=(
6767
'emerald_events /v1/emerald/events'
6868
'emerald_events_by_type /v1/emerald/events?type=accounts.transfer'
6969
'emerald_tokens /v1/emerald/evm_tokens'
70+
'emerald_tokens_sort_market_cap /v1/emerald/evm_tokens?sort_by=market_cap'
7071
'emerald_status /v1/emerald/status'
7172
'emerald_tx_volume /v1/emerald/stats/tx_volume'
7273
'emerald_contract_account /v1/emerald/accounts/oasis1qz2rynvcmrkwd57v00298uc2vtzgatde3cjpy72f'
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
{
2+
"evm_tokens": [],
3+
"is_total_count_clipped": false,
4+
"total_count": 0
5+
}
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
HTTP/1.1 200 OK
2+
Content-Type: application/json
3+
Vary: Origin
4+
Date: UNINTERESTING
5+
Content-Length: UNINTERESTING
6+
Lines changed: 167 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,167 @@
1+
{
2+
"evm_tokens": [
3+
{
4+
"contract_addr": "oasis1qqz8706pmf38wmptl6dkcaec8yykw0rvfv7ql6fc",
5+
"decimals": 18,
6+
"eth_contract_addr": "0xf02b3e437304892105992512539F769423a515Cb",
7+
"is_verified": true,
8+
"name": "YUZUToken",
9+
"num_holders": 15,
10+
"num_transfers": 108,
11+
"symbol": "YUZU",
12+
"total_supply": "324996573618707482993195360",
13+
"type": "ERC20",
14+
"verification_level": "partial"
15+
},
16+
{
17+
"contract_addr": "oasis1qpgcp5jzlgk4hcenaj2x82rqk8rrve2keyuc8aaf",
18+
"decimals": 18,
19+
"eth_contract_addr": "0x21C718C22D52d0F3a789b752D4c2fD5908a8A733",
20+
"is_verified": true,
21+
"name": "Wrapped ROSE",
22+
"num_holders": 14,
23+
"num_transfers": 48,
24+
"symbol": "wROSE",
25+
"total_supply": "11110528749907675559457292",
26+
"type": "ERC20",
27+
"verification_level": "partial"
28+
},
29+
{
30+
"contract_addr": "oasis1qp2hssandc7dekjdr6ygmtzt783k3gn38uupdeys",
31+
"decimals": 6,
32+
"eth_contract_addr": "0xdC19A122e268128B5eE20366299fc7b5b199C8e3",
33+
"is_verified": false,
34+
"name": "Tether USD",
35+
"num_holders": 9,
36+
"num_transfers": 33,
37+
"symbol": "USDT",
38+
"total_supply": "690015441212",
39+
"type": "ERC20"
40+
},
41+
{
42+
"contract_addr": "oasis1qzj2hwfs3yjm20jz5h70yk3etsst0k8s3cnl6l08",
43+
"decimals": 18,
44+
"eth_contract_addr": "0x941494A56164eA04d79f9867ddDB0Dd754A625cC",
45+
"is_verified": true,
46+
"name": "YuzuSwap LP Token",
47+
"num_holders": 4,
48+
"num_transfers": 2,
49+
"symbol": "LPT",
50+
"total_supply": "5515821744343857173275622",
51+
"type": "ERC20",
52+
"verification_level": "partial"
53+
},
54+
{
55+
"contract_addr": "oasis1qpuqs65me58n6mt05ezd7cnttx7k57w28v36l4ca",
56+
"decimals": 6,
57+
"eth_contract_addr": "0x81ECac0D6Be0550A00FF064a4f9dd2400585FE9c",
58+
"is_verified": false,
59+
"name": "USD Coin (Celer)",
60+
"num_holders": 3,
61+
"num_transfers": 6,
62+
"symbol": "ceUSDC",
63+
"total_supply": "160671058631",
64+
"type": "ERC20"
65+
},
66+
{
67+
"contract_addr": "oasis1qqehgt8jfnczmku5hazxkkprw5nqqk4nvunx9zf4",
68+
"decimals": 18,
69+
"eth_contract_addr": "0x28c9D3e689B5d3629aFC2D69ef6a2799578574e0",
70+
"is_verified": true,
71+
"name": "YuzuSwap LP Token",
72+
"num_holders": 2,
73+
"num_transfers": 1,
74+
"symbol": "LPT",
75+
"total_supply": "8543198732792740426556",
76+
"type": "ERC20",
77+
"verification_level": "partial"
78+
},
79+
{
80+
"contract_addr": "oasis1qzel2watfs6g3cm765dwlukymjs5k3rnhvua4z78",
81+
"decimals": 18,
82+
"eth_contract_addr": "0x3223f17957Ba502cbe71401D55A0DB26E5F7c68F",
83+
"is_verified": false,
84+
"name": "Wrapped Ether",
85+
"num_holders": 2,
86+
"num_transfers": 2,
87+
"symbol": "WETH",
88+
"total_supply": "153212215450000000000",
89+
"type": "ERC20"
90+
},
91+
{
92+
"contract_addr": "oasis1qpgvjkelzwd0yucjqyfpfzalrp3x74se7y922a7s",
93+
"decimals": 18,
94+
"eth_contract_addr": "0x485E6D145E958347EFDe7A43538879DCcD868f40",
95+
"is_verified": false,
96+
"name": "YuzuParkExtDummyToken",
97+
"num_holders": 1,
98+
"num_transfers": 2,
99+
"symbol": "YPEDT",
100+
"total_supply": "10000",
101+
"type": "ERC20"
102+
},
103+
{
104+
"contract_addr": "oasis1qqjv74rz8e6v9q6yn7y76zvf0yv5299ejsaxnjqu",
105+
"decimals": 18,
106+
"eth_contract_addr": "0xf5493ea940d12cE8594f81BaB2bB7d4ed81d49e8",
107+
"is_verified": false,
108+
"name": "xYUZU",
109+
"num_holders": 1,
110+
"num_transfers": 1,
111+
"symbol": "xYUZU",
112+
"total_supply": "72707317251766251839614070",
113+
"type": "ERC20"
114+
},
115+
{
116+
"contract_addr": "oasis1qrsl7tgujttvscfe2k268s7q2s7kdu9tyv9qv2tx",
117+
"decimals": 8,
118+
"eth_contract_addr": "0x5D9ab5522c64E1F6ef5e3627ECCc093f56167818",
119+
"is_verified": false,
120+
"name": "Wrapped BTC",
121+
"num_holders": 1,
122+
"num_transfers": 2,
123+
"symbol": "WBTC",
124+
"total_supply": "175579512",
125+
"type": "ERC20"
126+
},
127+
{
128+
"contract_addr": "oasis1qz29t7nxkwfqgfk36uqqs9pzuzdt8zmrjud5mehx",
129+
"decimals": 0,
130+
"eth_contract_addr": "0x1108A83b867c8b720fEa7261AE7A64DAB17B4159",
131+
"is_verified": false,
132+
"name": "MyNFT",
133+
"num_holders": 1,
134+
"num_transfers": 2,
135+
"symbol": "MNFT",
136+
"total_supply": "2",
137+
"type": "ERC721"
138+
},
139+
{
140+
"contract_addr": "oasis1qzpxtzc3xphccjq94wxffchfc5sua5t24vc6gvt6",
141+
"decimals": 18,
142+
"eth_contract_addr": "0x5C78A65AD6D0eC6618788b6E8e211F31729111Ca",
143+
"is_verified": true,
144+
"name": "Wrapped ROSE",
145+
"num_holders": 1,
146+
"num_transfers": 1,
147+
"symbol": "WROSE",
148+
"total_supply": "370854109276538025377920",
149+
"type": "ERC20",
150+
"verification_level": "partial"
151+
},
152+
{
153+
"contract_addr": "oasis1qzxx6htc6cceayd492mqt6lqc8l3eda29cnscx67",
154+
"decimals": 18,
155+
"eth_contract_addr": "0x0487F746B01A663108E7c4E5739F282491a45799",
156+
"is_verified": false,
157+
"name": "YuzuSwap LP Token",
158+
"num_holders": 1,
159+
"num_transfers": 4,
160+
"symbol": "LPT",
161+
"total_supply": "3454145239972177",
162+
"type": "ERC20"
163+
}
164+
],
165+
"is_total_count_clipped": false,
166+
"total_count": 13
167+
}
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
HTTP/1.1 200 OK
2+
Content-Type: application/json
3+
Vary: Origin
4+
Date: UNINTERESTING
5+
Transfer-Encoding: chunked
6+

0 commit comments

Comments
 (0)