{"id":17485682,"url":"https://github.com/mtefagh/fee","last_synced_at":"2025-04-10T14:05:59.563Z","repository":{"id":160510783,"uuid":"180459193","full_name":"mtefagh/fee","owner":"mtefagh","description":"Designed an attack for Vitalik's EIP 1559 and proposed an alternative transaction fee pricing protocol based on the Almgren-Chriss framework and median price auctions","archived":false,"fork":false,"pushed_at":"2021-08-08T14:22:45.000Z","size":672,"stargazers_count":6,"open_issues_count":0,"forks_count":2,"subscribers_count":0,"default_branch":"master","last_synced_at":"2024-10-19T05:22:37.952Z","etag":null,"topics":["cryptocurrency","ethereum-blockchain","game-theory","mechanism-design","simulation","transaction-fee"],"latest_commit_sha":null,"homepage":"https://mtefagh.github.io/fee/","language":"Jupyter Notebook","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/mtefagh.png","metadata":{"files":{"readme":"README.Rmd","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2019-04-09T22:32:04.000Z","updated_at":"2023-06-03T04:20:35.000Z","dependencies_parsed_at":null,"dependency_job_id":"6883b6ea-bde1-40a8-a56c-c890778de638","html_url":"https://github.com/mtefagh/fee","commit_stats":{"total_commits":25,"total_committers":2,"mean_commits":12.5,"dds":"0.43999999999999995","last_synced_commit":"7ef7535283351a21e9932f96459a76322b3b7842"},"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mtefagh%2Ffee","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mtefagh%2Ffee/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mtefagh%2Ffee/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mtefagh%2Ffee/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/mtefagh","download_url":"https://codeload.github.com/mtefagh/fee/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248231835,"owners_count":21069411,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["cryptocurrency","ethereum-blockchain","game-theory","mechanism-design","simulation","transaction-fee"],"created_at":"2024-10-19T02:08:28.859Z","updated_at":"2025-04-10T14:05:59.554Z","avatar_url":"https://github.com/mtefagh.png","language":"Jupyter Notebook","funding_links":[],"categories":[],"sub_categories":[],"readme":"---\ntitle: \"Median Price Auction\"\nauthor: \"Mojtaba Tefagh\"\ndate: \"4/9/2019\"\noutput:\n  md_document:\n    variant: markdown_github\n---\n\nWe first download the data from the Ethereum blockchain.\n\n```{python}\nimport pandas as pd\nimport numpy as np\nfrom web3 import Web3, HTTPProvider\n\n\nweb3 = Web3(HTTPProvider('http://localhost:8545'))\n\n    \nclass CleanTx():\n    \"\"\"transaction object / methods for pandas\"\"\"\n    def __init__(self, tx_obj):\n        self.hash = tx_obj.hash\n        self.block_mined = tx_obj.blockNumber\n        self.gas_price = tx_obj['gasPrice']\n        self.round_gp_10gwei()\n        \n    def to_dataframe(self):\n        data = {self.hash: {'block_mined':self.block_mined, 'gas_price':self.gas_price, 'round_gp_10gwei':self.gp_10gwei}}\n        return pd.DataFrame.from_dict(data, orient='index')\n\n    def round_gp_10gwei(self):\n        \"\"\"Rounds the gas price to gwei\"\"\"\n        gp = self.gas_price/1e8\n        if gp \u003e= 1 and gp \u003c 10:\n            gp = np.floor(gp)\n        elif gp \u003e= 10:\n            gp = gp/10\n            gp = np.floor(gp)\n            gp = gp*10\n        else:\n            gp = 0\n        self.gp_10gwei = gp\n\n\nblock_df = pd.DataFrame()\nfor block in range(5000000, 5000100, 1):\n    block_obj = web3.eth.getBlock(block, True)\n    for transaction in block_obj.transactions:\n        clean_tx = CleanTx(transaction)\n        block_df = block_df.append(clean_tx.to_dataframe(), ignore_index = False)\nblock_df.to_csv('tx.csv', sep='\\t', index=False)\n```\n\n```{r setup, include=FALSE}\nknitr::opts_chunk$set(echo=FALSE, warning=FALSE, message=FALSE)\n\nlibrary(tidyverse)\n```\n\n```{r}\ntx.raw \u003c- as.tbl(read.csv(\"tx.csv\", sep = \"\\t\"))\n```\n\nBefore we begin, some plots from the raw data (gas price will be normalized later):\n\n```{r}\nggplot(tx.raw,aes(x=block_mined, y=round_gp_10gwei))+geom_point()+labs(title=\"Gas Price\")\nggplot(tx.raw,aes(x=block_mined, y=gas_price))+geom_point()\n```\n\nNow, we throw out the `round_gp_10gpwei` column and divide the `gas_price` by $10^8$. Then we group our gas prices data by the blocks and we compute a summary (`min,median,mean,max`). The blocks are consecutive and their numbers are made to start from zero in order to have a bit more visually appealing plots!\n\n\n```{r}\ntx.summary \u003c- tx.raw %\u003e% select(-round_gp_10gwei) %\u003e%\n  mutate(gas_price=gas_price/10^8,block_mined=block_mined-min(block_mined)) %\u003e% \n  group_by(block_mined) %\u003e%\n  summarise_at(.vars=vars(gas_price),.funs=funs(min(.),median(.),mean(.),max(.)))\n```\n\n\nHere are some plots. `geom_smooth()` uses by default the Local Regression (`loess` for short):\n\n*Loess Regression is the most common method used to smoothen a volatile time series. It is a non-parametric methods where least squares regression is performed in localized subsets, which makes it a suitable candidate for smoothing any numerical vector.*\n\nTo show the effectiveness/stability of median over other methods, we plot the data points along with the prediction curve of each (`min,median,mean,max`). Notice the scale of `max` is quite different therefore, although it seems stable its prediction curve has much higher errors than median. See the last two plots to compare the scale of their fluctutations.\n\n\n```{r}\nggplot(tx.summary,aes(x=block_mined,y=min))+geom_smooth()+geom_point()+labs(title=\"min of gas prices\")\n```\n\n\n```{r}\nggplot(tx.summary,aes(x=block_mined,y=mean))+geom_smooth()+geom_point()+labs(title=\"mean of gas prices\")\n```\n\n\n\n```{r}\nggplot(tx.summary,aes(x=block_mined,y=max))+geom_smooth()+geom_point()+labs(title=\"max of gas prices\")\n```\n\n\n```{r}\nggplot(tx.summary,aes(x=block_mined,y=median))+geom_smooth()+geom_point()+labs(title=\"median of gas prices\")\n```\n\n\n\n\n\nHere is the max, median, and min statistics summary plot:\n\n```{r}\nggplot(data = tx.raw %\u003e% group_by(block_mined)) + \n       stat_summary(\n             mapping = aes(x = block_mined, y = gas_price),\n             fun.ymin = min,\n             fun.ymax = max,\n             fun.y = median\n         )+labs(title=\"Summary of gas_prices\")\n```\n\n\nHere is how the mean and median and minimum curves compare:\n\n```{r}\nggplot(tx.summary,aes(x=block_mined))+geom_smooth(aes(y=min,colour=\"min\"))+\n  geom_smooth(aes(y=median,colour=\"median\"))+geom_smooth(aes(y=mean,colour=\"mean\"))+labs(title=\"min_median_mean\")+ylab(\"min_median_mean\")+scale_colour_manual(name=\"legend\", values=c(\"blue\", \"red\",\"green\"))\n\n```\n\nHere is how all curves compare:\n\n```{r}\nggplot(tx.summary,aes(x=block_mined))+geom_smooth(aes(y=mean,colour=\"mean\"))+geom_smooth(aes(y=median,colour=\"median\"))+geom_smooth(aes(y=min,colour=\"min\"))+geom_smooth(aes(y=max,colour=\"max\"))+\n  labs(title=\"Summary gas prices\")+ylab(\"min_median_mean_max\")+scale_colour_manual(name=\"legend\", values=c(\"blue\", \"red\",\"green\",\"black\"))\n```\n\n\u003c!-- Let us see how the method `gam` errors compare in each case: --\u003e\n\u003c!-- Here you will first need to normalized each column to make this meaningful --\u003e\n\u003c!-- ```{r} --\u003e\n\u003c!-- gam.med \u003c- gam(min_gas_price~block_mined,data=tx.summary) --\u003e\n\u003c!-- gam.med$deviance --\u003e\n\u003c!-- ``` --\u003e\n\n\n\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmtefagh%2Ffee","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmtefagh%2Ffee","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmtefagh%2Ffee/lists"}