-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
a859083
commit d0c2406
Showing
34 changed files
with
3,755 additions
and
10,073 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -3,23 +3,21 @@ name: CI Workflow | |
on: [push] | ||
|
||
jobs: | ||
|
||
# Linting with Pre-commit | ||
lint: | ||
ruff: | ||
runs-on: ubuntu-latest | ||
|
||
steps: | ||
- uses: actions/checkout@v3 | ||
- uses: actions/checkout@v4 | ||
- uses: astral-sh/ruff-action@v1 | ||
|
||
- name: Setup Python 3.12.6 | ||
- name: Set up Python 3.12.6 | ||
uses: actions/setup-python@v5 | ||
with: | ||
python-version: 3.12.6 | ||
|
||
# Run pre-commit hooks (e.g., black, flake8, isort) | ||
- uses: pre-commit/[email protected] | ||
|
||
|
||
# Test runs | ||
tests: | ||
runs-on: ubuntu-latest | ||
|
@@ -28,31 +26,24 @@ jobs: | |
fail-fast: false | ||
|
||
steps: | ||
- uses: actions/checkout@v3 | ||
- uses: actions/checkout@v4 | ||
|
||
# Install Solidity compiler (solc) | ||
- name: Install solc | ||
run: | | ||
sudo add-apt-repository -y ppa:ethereum/ethereum | ||
sudo apt-get update | ||
sudo apt-get install -y solc | ||
- name: Install uv | ||
uses: astral-sh/setup-uv@v3 | ||
with: | ||
version: "0.4.18" | ||
enable-cache: true # Enables built-in caching for uv | ||
|
||
# install poetry to allow cacheing | ||
- name: Install poetry | ||
run: pipx install poetry | ||
- name: Set up Python 3.12.6 | ||
run: uv python install 3.12.6 | ||
|
||
- name: Setup Python 3.12.6 | ||
uses: actions/setup-python@v5 | ||
with: | ||
python-version: 3.12.6 | ||
cache: 'poetry' | ||
# Install dependencies with all extras (including dev) | ||
- name: Install Requirements | ||
run: | | ||
poetry config virtualenvs.in-project true | ||
poetry install | ||
run: uv sync --extra=dev | ||
|
||
# Run tests with environment variables | ||
- name: Run Tests | ||
env: | ||
ETH_RPC_URL: ${{ secrets.ETH_RPC_URL }} | ||
ETHERSCAN_API_KEY: ${{ secrets.ETHERSCAN_API_KEY }} | ||
run: | | ||
poetry run pytest -n auto | ||
run: uv run pytest -n auto |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,167 @@ | ||
# pragma version ~=0.4 | ||
|
||
""" | ||
@title Temporary Deposit Limit Module for yearn vaults | ||
@notice This contract temporarily controls deposits into a yearn vault and manages roles (admin and security_agent). | ||
@dev Admins can appoint new admins and security_agents, while security_agents can pause or resume deposits. | ||
This module will be removed once the vault is battle-tested and proven stable. | ||
""" | ||
|
||
|
||
################################################################ | ||
# INTERFACES # | ||
################################################################ | ||
|
||
from interfaces import IVault | ||
|
||
################################################################ | ||
# STORAGE # | ||
################################################################ | ||
|
||
# Two main roles: admin and security_agent | ||
is_admin: public(HashMap[address, bool]) | ||
is_security_agent: public(HashMap[address, bool]) | ||
|
||
# Main contract state for deposit control | ||
deposits_paused: public(bool) | ||
|
||
# Max deposit limit | ||
max_deposit_limit: public(uint256) | ||
|
||
# Stablecoin/Vault addresses | ||
vault: public(immutable(IVault)) | ||
|
||
################################################################ | ||
# CONSTRUCTOR # | ||
################################################################ | ||
|
||
@deploy | ||
def __init__( | ||
_vault: IVault, | ||
max_deposit_limit: uint256, | ||
): | ||
""" | ||
@notice Initializes the contract by assigning the deployer as the initial admin and security_agent. | ||
""" | ||
self._set_admin(msg.sender, True) | ||
self._set_security_agent(msg.sender, True) | ||
self._set_deposits_paused(False) # explicit non-paused at init | ||
self._set_deposit_limit(max_deposit_limit) | ||
|
||
vault = _vault | ||
|
||
|
||
################################################################ | ||
# INTERNAL FUNCTIONS # | ||
################################################################ | ||
|
||
@internal | ||
def _set_admin(_address: address, is_admin: bool): | ||
""" | ||
@notice Internal function to assign or revoke admin role. | ||
@param address The address to be granted or revoked admin status. | ||
@param is_admin Boolean indicating if the address should be an admin. | ||
""" | ||
self.is_admin[_address] = is_admin | ||
|
||
|
||
@internal | ||
def _set_security_agent(_address: address, is_security_agent: bool): | ||
""" | ||
@notice Internal function to assign or revoke security_agent role. | ||
@param address The address to be granted or revoked security_agent status. | ||
@param is_security_agent Boolean indicating if the address should be a security_agent. | ||
""" | ||
self.is_security_agent[_address] = is_security_agent | ||
|
||
|
||
@internal | ||
def _set_deposits_paused(is_paused: bool): | ||
""" | ||
@notice Internal function to pause or unpause deposits. | ||
@param is_paused Boolean indicating if deposits should be paused. | ||
""" | ||
self.deposits_paused = is_paused | ||
|
||
|
||
@internal | ||
def _set_deposit_limit(new_limit: uint256): | ||
""" | ||
@notice Internal function to set the maximum deposit limit. | ||
@param new_limit The new maximum deposit limit. | ||
""" | ||
self.max_deposit_limit = new_limit | ||
|
||
|
||
################################################################ | ||
# EXTERNAL FUNCTIONS # | ||
################################################################ | ||
|
||
@external | ||
def set_admin(new_admin: address, is_admin: bool): | ||
""" | ||
@notice Allows an admin to grant or revoke admin role to another address. | ||
@param new_admin The address to grant or revoke admin role. | ||
@param is_admin Boolean indicating if the address should be an admin. | ||
@dev Only callable by an admin. | ||
""" | ||
assert self.is_admin[msg.sender], "Caller is not an admin" | ||
self._set_admin(new_admin, is_admin) | ||
|
||
|
||
@external | ||
def set_security_agent(new_security_agent: address, is_security_agent: bool): | ||
""" | ||
@notice Allows an admin to grant or revoke security_agent role to another address. | ||
@param new_security_agent The address to grant or revoke security_agent role. | ||
@param is_security_agent Boolean indicating if the address should be a security_agent. | ||
@dev Only callable by an admin. | ||
""" | ||
assert self.is_admin[msg.sender], "Caller is not an admin" | ||
self._set_security_agent(new_security_agent, is_security_agent) | ||
|
||
|
||
@external | ||
def set_deposits_paused(state: bool): | ||
""" | ||
@notice Allows a security_agent to pause or resume deposits. | ||
@param state Boolean indicating the desired paused state for deposits. | ||
@dev Only callable by a security_agent. | ||
""" | ||
assert self.is_security_agent[msg.sender], "Caller is not a security_agent" | ||
self._set_deposits_paused(state) | ||
|
||
|
||
@external | ||
def set_deposit_limit(new_limit: uint256): | ||
""" | ||
@notice Allows an admin to update the maximum deposit limit. | ||
@param new_limit The new maximum deposit limit. | ||
@dev Only callable by an admin. | ||
""" | ||
assert self.is_admin[msg.sender], "Caller is not an admin" | ||
self._set_deposit_limit(new_limit) | ||
|
||
|
||
################################################################ | ||
# VIEW FUNCTIONS # | ||
################################################################ | ||
|
||
@view | ||
@external | ||
def available_deposit_limit(receiver: address) -> uint256: | ||
""" | ||
@notice Checks the available deposit limit for a given receiver. | ||
@param receiver The address querying deposit limit. | ||
@return uint256 Returns the maximum deposit limit if deposits are not paused, otherwise returns 0. | ||
""" | ||
if self.deposits_paused: | ||
return 0 | ||
if self.max_deposit_limit == max_value(uint256): | ||
return max_value(uint256) | ||
else: | ||
vault_balance: uint256 = staticcall vault.totalAssets() | ||
if vault_balance >= self.max_deposit_limit: | ||
return 0 | ||
else: | ||
return self.max_deposit_limit - vault_balance |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -3,4 +3,5 @@ | |
def weight() -> uint256: | ||
... | ||
|
||
|
||
# eip165 hash of this inteface is: 0xA1AAB33F |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,6 @@ | ||
# pragma version ~=0.4.0 | ||
|
||
|
||
@view | ||
@external | ||
def debt() -> uint256: | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.