Skip to content

Commit cca4665

Browse files
authored
Accurate gas distribution across assets consumed within the same tx (#806)
1 parent a4f72f1 commit cca4665

2 files changed

Lines changed: 58 additions & 9 deletions

File tree

df_py/volume/queries.py

Lines changed: 41 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -451,6 +451,36 @@ def _queryNftinfo(chainID, endBlock) -> List[SimpleDataNft]:
451451
return nftinfo
452452

453453

454+
def _calculate_gas_vols(
455+
txgascost: Dict[str, Dict[str, float]], native_token_addr: str
456+
) -> Dict[str, Dict[str, float]]:
457+
"""
458+
@description
459+
Calculate the gas volumes attributed to each NFT based on shared transaction gas costs.
460+
461+
@arguments
462+
txgascost (Dict[str, Dict[str, float]]): A dictionary mapping transaction hashes to another dictionary,
463+
where the inner dictionary maps NFT addresses to their tx associated gas costs.
464+
native_token_addr (str): The address of the native token used to pay for gas.
465+
466+
@return
467+
Dict[str, Dict[str, float]]: A dictionary mapping the native token address to another dictionary,
468+
where the inner dictionary maps NFT addresses to the gas volumes attributed to them.
469+
"""
470+
gasvols: Dict[str, Dict[str, float]] = {}
471+
gasvols[native_token_addr] = {}
472+
for tx in txgascost:
473+
nfts = txgascost[tx].keys()
474+
gas_cost = list(txgascost[tx].values())[0]
475+
tot_nfts = len(nfts)
476+
gas_attributed = gas_cost / tot_nfts
477+
478+
for nft in nfts:
479+
gasvols[native_token_addr].setdefault(nft, 0)
480+
gasvols[native_token_addr][nft] += gas_attributed
481+
return gasvols
482+
483+
454484
@enforce_types
455485
def _queryVolsOwners(
456486
st_block: int, end_block: int, chainID: int
@@ -468,7 +498,8 @@ def _queryVolsOwners(
468498
vols: Dict[str, Dict[str, float]] = {}
469499
gasvols: Dict[str, Dict[str, float]] = {}
470500
owners: Dict[str, float] = {}
471-
txgascost: Dict[str, float] = {} # tx hash : gas cost
501+
txgascost: Dict[str, Dict[str, float]] = {} # tx hash : gas cost
502+
native_token_addr = networkutil._CHAINID_TO_ADDRS[chainID].lower()
472503

473504
chunk_size = 1000 # max for subgraph = 1000
474505
offset = 0
@@ -530,16 +561,14 @@ def _queryVolsOwners(
530561

531562
# deduct 1 wei so it's not profitable for free assets
532563
gasCost = from_wei(gasCostWei - 1)
533-
native_token_addr = networkutil._CHAINID_TO_ADDRS[chainID].lower()
534564

535565
# add gas cost value
536-
if gasCost > 0 and order["tx"] not in txgascost:
537-
if native_token_addr not in gasvols:
538-
gasvols[native_token_addr] = {}
539-
if nft_addr not in gasvols[native_token_addr]:
540-
gasvols[native_token_addr][nft_addr] = 0
541-
txgascost[order["tx"]] = gasCost
542-
gasvols[native_token_addr][nft_addr] += gasCost
566+
if gasCost > 0:
567+
if order["tx"] not in txgascost:
568+
txgascost[order["tx"]] = {}
569+
if nft_addr not in txgascost[order["tx"]]:
570+
txgascost[order["tx"]][nft_addr] = 0
571+
txgascost[order["tx"]][nft_addr] = gasCost
543572

544573
if lastPriceValue == 0:
545574
continue
@@ -552,6 +581,9 @@ def _queryVolsOwners(
552581
vols[basetoken_addr][nft_addr] = 0.0
553582
vols[basetoken_addr][nft_addr] += lastPriceValue
554583

584+
# calculate gas vols
585+
gasvols = _calculate_gas_vols(txgascost, native_token_addr)
586+
555587
print("_queryVolsOwners(): done")
556588
return (vols, owners, gasvols)
557589

df_py/volume/test/test_queries.py

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1053,6 +1053,23 @@ def test_process_delegations(w3):
10531053
]
10541054

10551055

1056+
def test_calculate_gas_vols_distributes_gas_evenly():
1057+
txgascost = {
1058+
"tx1": {"nft1": 100.0, "nft2": 100.0},
1059+
"tx2": {"nft2": 100.0},
1060+
"tx3": {"nft3": 200.0},
1061+
}
1062+
native_token_addr = "token1"
1063+
1064+
expected_gasvols = {"token1": {"nft1": 50.0, "nft2": 150.0, "nft3": 200.0}}
1065+
1066+
calculated_gasvols = queries._calculate_gas_vols(txgascost, native_token_addr)
1067+
1068+
assert (
1069+
calculated_gasvols == expected_gasvols
1070+
), "Gas volumes should be evenly distributed among NFTs."
1071+
1072+
10561073
# ===========================================================================
10571074
# support functions
10581075

0 commit comments

Comments
 (0)