defi-savings
Deposit USDC into Aave v3 on Base and let it accrue yield. The library is wallet-agnostic: bring your own signer.
Install
pip install defi-savings
# or
uv add defi-savings
Requires Python 3.11+.
Signers
The library separates what to call on Aave from how to sign the transaction. Pick the signer that matches your setup.
EOA
Single private key. Submits approve and supply as two sequential transactions.
from defi_savings import AaveProvider, EOASigner
provider = AaveProvider(
EOASigner(
private_key="0x...",
rpc_url="https://mainnet.base.org",
)
)
Gnosis Safe
2-of-N multisig. Batches approve and supply into one atomic MultiSend transaction. No gnosis-py dependency required.
from defi_savings import AaveProvider, GnosisSafeSigner
provider = AaveProvider(
GnosisSafeSigner(
safe_address="0x...",
signer1_key="0x...",
signer2_key="0x...",
rpc_url="https://mainnet.base.org",
)
)
Custom wallet
Implement three methods to support any signing setup: Coinbase MPC, Fireblocks, hardware signers, or anything else that can sign an Ethereum transaction.
from defi_savings import Signer, Call
class MyCoinbaseWalletSigner(Signer):
@property
def address(self) -> str:
return "0x..." # where the USDC lives
@property
def w3(self):
return self._w3 # Web3 instance used for read-only calls
def execute(self, calls: list[Call]) -> str:
# sign and submit however your wallet works
# return the tx hash
...
Usage
from decimal import Decimal
# Deposit $1000 USDC from the signer address into Aave
tx = provider.deposit(Decimal("1000"))
# Balance includes principal and all accrued yield
balance = provider.position_balance() # Decimal("1004.823100")
# Live APY
apy = provider.current_apy() # Decimal("4.82")
# Withdraw $500 back to the signer address
tx = provider.withdraw(Decimal("500"))
Provider methods are synchronous (Web3.py). In async code, wrap with asyncio.to_thread().
balance = await asyncio.to_thread(provider.position_balance)
Yield distribution
If multiple users share a single treasury, use distribute_yield to split accrued interest proportionally. It is a pure function with no I/O.
from defi_savings import AccountSnapshot, distribute_yield
from decimal import Decimal
snapshots = [
AccountSnapshot("alice", balance=Decimal("1000"), last_snapshot=Decimal("1000")),
AccountSnapshot("bob", balance=Decimal("3000"), last_snapshot=Decimal("3000")),
]
distributions = distribute_yield(snapshots, provider.position_balance())
# [("alice", Decimal("25.000000")), ("bob", Decimal("75.000000"))]
After crediting each user, set last_snapshot = balance + yield_amt so the next run only measures new growth.
Custom protocols
Implement YieldProvider to use Morpho, Compound, or any other protocol. The signer stays the same.
from defi_savings import YieldProvider, Signer
from decimal import Decimal
class MorphoProvider(YieldProvider):
name = "morpho-base"
def __init__(self, signer: Signer): ...
def deposit(self, amount_usdc: Decimal) -> str: ...
def withdraw(self, amount_usdc: Decimal) -> str: ...
def position_balance(self) -> Decimal: ...
def current_apy(self) -> Decimal: ...
Running tests
uv sync --dev
pytest
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file defi_savings-0.1.0.tar.gz.
File metadata
- Download URL: defi_savings-0.1.0.tar.gz
- Upload date:
- Size: 11.0 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via:
uv/0.8.4
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
35598a9f6723602d1273dbdda339f82689af6156d03402f75ce78a7f68ef94b3
|
|
| MD5 |
72347f21011d60157e3d072426332652
|
|
| BLAKE2b-256 |
71cf92532d26e4222060f46ee7d52f1a848934571ad837140974dcf4b22c7e86
|
File details
Details for the file defi_savings-0.1.0-py3-none-any.whl.
File metadata
- Download URL: defi_savings-0.1.0-py3-none-any.whl
- Upload date:
- Size: 12.6 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via:
uv/0.8.4
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
f3a15527ed4b76797694a76d98a2eff60d8ea652a5f7e396a3c75f8aaa6e14b9
|
|
| MD5 |
c14bec6633bea6d8bba12f43ff813608
|
|
| BLAKE2b-256 |
8641a3223c8fe53b8aea9276facdf64bf16e0d1a67a199c520ea45aec9913246
|