{"id":13767213,"url":"https://github.com/philogy/meth-weth","last_synced_at":"2025-04-12T14:08:03.479Z","repository":{"id":64046598,"uuid":"571383824","full_name":"Philogy/meth-weth","owner":"Philogy","description":"The most optimized ERC20 \u0026 Wrapped Ether implementation.","archived":false,"fork":false,"pushed_at":"2023-12-31T16:03:03.000Z","size":443,"stargazers_count":145,"open_issues_count":0,"forks_count":8,"subscribers_count":4,"default_branch":"main","last_synced_at":"2025-03-26T08:47:32.278Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"Solidity","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Philogy.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":"SECURITY.md","support":null,"governance":null,"roadmap":null,"authors":null}},"created_at":"2022-11-28T02:07:31.000Z","updated_at":"2025-03-09T17:31:17.000Z","dependencies_parsed_at":"2023-02-18T10:32:10.481Z","dependency_job_id":"ca7e2571-86a3-446b-bb11-1646642e44ce","html_url":"https://github.com/Philogy/meth-weth","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Philogy%2Fmeth-weth","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Philogy%2Fmeth-weth/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Philogy%2Fmeth-weth/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Philogy%2Fmeth-weth/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Philogy","download_url":"https://codeload.github.com/Philogy/meth-weth/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248578866,"owners_count":21127713,"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":[],"created_at":"2024-08-03T16:01:06.204Z","updated_at":"2025-04-12T14:08:03.457Z","avatar_url":"https://github.com/Philogy.png","language":"Solidity","funding_links":[],"categories":["Huff projects you can learn from and contribute to"],"sub_categories":[],"readme":"# METH\n\n\u003e A Wrapped Ether implementation so efficient it'll make your teeth fall out 🦷\n\n\"METH\" is an overall better version of the commonly used [WETH9](https://etherscan.io/token/0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2) contract,\nproviding a trustless, immutable and standardized way for smart contracts to abstract away the\ndifference between the native ETH asset and fungible [ERC20](https://eips.ethereum.org/EIPS/eip-20) tokens.\n\n## 🪨 Deployed Instances\n\n(pending final implementation and audits)\n\n## 🏆 Gas Use: METH vs WETH9\n\n**STILL A WORK IN PROGRESS, MORE COMPARISONS PENDING**\n\nComparison may improve in favor of _METH_ if more optimizations are found.\n\n\n### Direct Calls\nThis table contains a comparison of gas costs for limited function calls.\n\n|Action|WETH9|METH|Difference|Added Details|\n|------|-----|----|----------|-------------|\n|`deposit()`|45,038|44,501|-537|Wrap non-zero amount with no existing balance|\n|`transfer(...)`|51,534|50,560|-974|Transfer to account with zero balance|\n|receive-fallback|27,631|27,333|-298|Wrap non-zero amount with existing balance|\n|`approve(...)`|46,364|45,465|-899|Grant infinite allowance (requires truncating calldata for METH)|\n|`withdraw(...)`|35,144|34,395|-749|Unwrap specific amount|\n|`transferFrom(...)`|36,965|36,033|-932|Transfer from non-zero to non-zero with infinite approval|\n|`transferFrom(...)`|35,688|34,158|-1,530|Transfer from non-zero to non-zero with finite approval|\n|withdraw all remaining balance|30,344|29,430|-914|Unwrap all remaining (`withdraw(uint)` in WETH, `withdrawAll()` in METH)|\n\n\n## ✅ Why METH over WETH9?\n\n### 🔒 Fewer Footguns\n\nWETH9 does not have a `permit` method but implements a silent fallback method meaning it'll silently accept\na call to all methods, even ones it hasn't implemented. This often leads to unforseen\nvulnerabilities when developers expect their contracts to interact with ERC20 tokens that implement\ncertain methods or at the very least to revert if they do not implement the methods. This was e.g. the\ncause of [Multicoin's $ 1M bridge hack](https://medium.com/zengo/without-permit-multichains-exploit-explained-8417e8c1639b).\n\n_METH_ does **not** have a silent fallback method and will revert if it's called for a method it\nhasn't implemented. _METH_ does however implement a payable `receive` fallback method. Allowing you to wrap ETH\nif you explicitly send ETH to the contract along with no calldata.\n\n### 🧩 Backwards Compatible\n\nThe previously existing `withdraw`, `deposit` and `receive` fallback method behave like WETH9's\nmethods meaning it's a drop-in replacement.\n\nThe only difference that may have to be considered:\nCalling methods that are not implemented will not silently pass, if you need to wrap ETH to WETH\neither send it directly with no calldata or use one of the `deposit` methods. Calling an\nunimplemented function _may_ consume all gas sent to the contract.\n\nFollowing (unimplemented) selectors will lead to an exceptional revert, consuming all gas when\ncalled:\n```\n0x0a000000 - 0x0affffff\n0x21000000 - 0x21ffffff\n0x24000000 - 0x24ffffff\n0x29000000 - 0x29ffffff\n0x2f000000 - 0x2fffffff\n0x4b000000 - 0x4bffffff\n0x86000000 - 0x86ffffff\n0xaa000000 - 0xaaffffff\n0xae000000 - 0xaeffffff\n0xcb000000 - 0xcbffffff\n```\n\n### 👤 Improved UX\n\n\n\n### 💻 Improved Contract-level Interaction\n\nCommon patterns are made more efficient by packing them into single calls. Beyond saving on call\noverhead the methods are also more efficient because they don't need to update intermediary storage\nvariables. Certain methods also allow contracts to avoid otherwise unused `receive` / payable `fallback` methods.\n\n- `METH.depositTo{ value: amount }(recipient);` replaces:\n  ```solidity\n  WETH9.deposit{ value: amount}();\n  WETH9.transfer(recipient, amount);\n  ```\n- `METH.depositAndApprove{ value: amount }(spender, amount);` replaces:\n  ```solidity\n  WETH9.deposit{ value: amount}();\n  WETH9.approve(spender, amount);\n  ```\n- `METH.withdrawTo(recipient, amount);` replaces:\n  ```solidity\n  receive() external payable {\n      require(msg.sender == address(WETH));\n  }\n  // ...\n  WETH9.withdraw(amount);\n  SafeTransferLib.safeTransferETH(recipient, amount);\n  ```\n- `METH.withdrawFrom(account, amount);` replaces:\n  ```solidity\n  WETH9.transferFrom(account, address(this), amount);\n  WETH9.withdraw(amount);\n  ```\n- `METH.withdrawFromTo(from, recipient, amount);` replaces:\n  ```solidity\n  receive() external payable {\n      require(msg.sender == address(WETH));\n  }\n  // ...\n  WETH9.transferFrom(from, address(this), amount);\n  WETH9.withdraw(amount);\n  SafeTransferLib.safeTransferETH(recipient, amount);\n  ```\n- `METH.withdrawAll();` replaces:\n  ```solidity\n  WETH9.withdraw(WETH9.balanceOf(address(this)));\n  ```\n- `METH.withdrawAllTo(recipient);` replaces:\n  ```solidity\n  receive() external payable {\n      require(msg.sender == address(WETH));\n  }\n  // ...\n  uint amount = WETH9.balanceOf(address(this));\n  WETH9.withdraw(amount);\n  SafeTransferLib.safeTransferETH(recipient, amount);\n  ```\n\n### ⚡ Highly Optimized\n_METH_ is written directly in bytecode-level assembly using the [Huff](https://huff.sh) language, ensuring its implementation is as efficient\nas possible.\n\n## ⚙️ \"METH\" under the hood\n\n### Storage Layout\nTo save gas a non-standard storage layout is used:\n\nSlot Name | Slot Determination | Values Stored (Bits)\n----|----|----\nMain Data of `account` | `slot = account_address` | (255-128: `nonce`, 127-0: `balance`)\nAllowance from `spender` for `owner` | `slot = keccak256(abi.encode(owner, spender))` | (255-0: `allowance`)\n\nThe layout ensures minimal overhead when storing balances. The layout however also makes it possible\nfor an allowance and balance slot to collide. Making it possible for someone to destroy WETH or mint\nunsusable WETH by finding an allowance slot with 12 leading zero bytes (96-bit bruteforce). For more\ndetails on the implications of this view the [Security doc](./SECURITY.md).\n\n### Function Dispatcher\nMETH uses a constant gas function dispatcher that jumps to any function in its ABI in only 34-gas:\n\nStep gas cost|Cumulative gas cost|Op-Code |Stack|Explanation\n-------------|---------------|------------------|-----|----------------\n2|2|PUSH0|[`0`]|Push 0 using 2 gas ([EIP-3855](https://eips.ethereum.org/EIPS/eip-3855) included in the Shangai upgrade)\n3|5|CALLDATALOAD|[`calldata[0:32]`]|Load calldata (including selector)\n3|8|PUSH1 0xE0|[`0xe0 (224)`; `calldata[0:32]`]|Push selector offset\n3|11|SHR|[`selector`]|Bitshift right to get 4 upper most bytes of calldata i.e. selector\n3|14|DUP1|[`selector`; `selector`]|Duplicate selector on stack for jump table\n3|17|PUSH1 0x12|[`0x12 (18)`, `selector`; `selector`]|Push unique selector bits offset\n3|20|SHR|[`unique_bits`; `selector`]|Bitshift right to get the 14 uppermost bits of the selector\n3|23|PUSH1 0x3F|[`0x3f (0b111111)`; `unique_bits`; `selector`]|Push lower bit mask\n3|26|OR|[`jump_destination`; `selector`]|Masks lower bits to ensure there's sufficient space between destinations\n8|34|JUMP|[`selector`]|Jump to function.\n\nEach function verifies whether the selector matches its function selector as whole, this is done to\nensure that the contract actually reverts if it's called with a selector where the identifying\n8-bits match with an existing function but the full selector does not e.g. (from `name()`):\n\nStep gas cost|Cumulative gas cost|Op-Code |Stack|Explanation\n-------------|---------------|------------------|-----|----------------\n1|1|JUMPDEST|[`selector`]|\"Landing pad\" of function from dispatcher\n3|4|PUSH4 0x06fdde03|[`name.selector`, `selector`]|Pushes expected selector to stack\n3|7|SUB|[`selector_diff`]|Use subtraction operator as inequality check\n2|9|CALLVALUE|[`msg.value`, `selector_diff`]|Push `msg.value`\n3|12|OR|[`invalid_call`]|Bitwise OR results in non-zero value if either selector didn't match or ETH was sent\n3|15|PUSH2 0x40e1|[`revert_dest`, `invalid_call`]|Pushes revert destination to stack\n10|25|JUMPI|[]|Jumps to a revert if `invalid_call` is non-zero\n\nDue to the cost of the `JUMPI` opcode some functions that have more conditions defer the actual \nbranching instruction until it can bundle together the check of multiple conditions e.g.\n`withdraw(uint)` uses only 1 `JUMPI` to check both the selector and that the caller has sufficient\nbalance.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fphilogy%2Fmeth-weth","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fphilogy%2Fmeth-weth","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fphilogy%2Fmeth-weth/lists"}