Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Uniswap v3 valuation and swaps on Base #255

Merged
merged 20 commits into from
Dec 24, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -29,4 +29,6 @@ docs/source/tutorials/aave.json
contracts/aave-v3-deploy/hardhat-deployment-export.json

# pyenv local
.python-version
.python-version

contracts/lagoon-v0
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,10 @@
# Current

- Add Multicall3 support in `multicall_batcher` module
- Add `SwapRouter02` support on Base for doing Uniswap v3 swaps
- Add Uniswap V3 quoter for the valuation
- Add `buy_tokens()` helper to buy multiple tokens once, automatically look up best routes

# 0.27

- Add: Support for [Velvet Capital vaults](https://www.velvet.capital/)
Expand Down
48 changes: 44 additions & 4 deletions eth_defi/abi.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
import re
from functools import lru_cache
from pathlib import Path
from typing import Optional, Sequence, Type, Union
from typing import Optional, Sequence, Type, Union, Any

import eth_abi
from eth_abi import decode
Expand All @@ -27,12 +27,20 @@
# Cache loaded ABI files in-process memory for speedup
from web3.datastructures import AttributeDict

from eth_defi.utils import ZERO_ADDRESS_STR

# How big are our ABI and contract caches
_CACHE_SIZE = 512


#: Ethereum 0x0000000000000000000000000000000000000000 address as a string.
#:
#: Legacy. Use one below.
#:
ZERO_ADDRESS_STR = "0x0000000000000000000000000000000000000000"

#: Ethereum 0x0000000000000000000000000000000000000000 address
ZERO_ADDRESS = ZERO_ADDRESS_STR


@lru_cache(maxsize=_CACHE_SIZE)
def get_abi_by_filename(fname: str) -> dict:
"""Reads a embedded ABI file and returns it.
Expand Down Expand Up @@ -288,6 +296,34 @@ def encode_function_args(func: ContractFunction, args: Sequence) -> bytes:
return encoded_args


def decode_function_output(func: ContractFunction, data: bytes) -> Any:
"""Decode raw return value of Solidity function using Contract proxy object.

Uses `web3.Contract.functions` prepared function as the ABI source.

:param func:
Function which arguments we are going to encode.

Must be bound.

:param result:
Raw encoded Solidity bytes.
"""
assert isinstance(func, ContractFunction)

web3 = func.w3

fn_abi, fn_selector, aligned_fn_arguments = get_function_info(
func.fn_name,
web3.codec,
func.contract_abi,
args=func.args,
)
arg_types = [t["type"] for t in fn_abi["outputs"]]
decoded_out = eth_abi.decode(arg_types, data)
return decoded_out


def encode_function_call(
func: ContractFunction,
args: Sequence,
Expand Down Expand Up @@ -320,7 +356,10 @@ def encode_function_call(
fn_abi,
args,
)
encoded = encode_abi(w3, fn_abi, fn_arguments, fn_selector)
try:
encoded = encode_abi(w3, fn_abi, fn_arguments, fn_selector)
except Exception as e:
raise RuntimeError(f"Could not encode ABI: {fn_abi}, args: {fn_arguments}") from e
return HexBytes(encoded)


Expand Down Expand Up @@ -464,3 +503,4 @@ def get_function_selector(func: ContractFunction) -> bytes:
function_signature = _abi_to_signature(fn_abi)
fn_selector = function_signature_to_4byte_selector(function_signature) # type: ignore
return fn_selector

1 change: 1 addition & 0 deletions eth_defi/abi/multicall/IMulticall3.json

Large diffs are not rendered by default.

Loading