The pUSD Manager Vyper is a smart contract system implemented in Vyper for managing pUSD, a stablecoin in the VolumeFi ecosystem. This contract facilitates the minting, burning, and overall management of pUSD tokens, ensuring stability and security within the decentralized finance (DeFi) space.
This repository contains the Vyper implementation of the pUSD Manager contract system, consisting of four main contracts:
pusd_manager.vy
- Main pUSD manager contract for Ethereum mainnetpusd_manager_xdai.vy
- pUSD manager contract for xDai networkpusd_connector.vy
- Connector contract for cross-chain operationspurchaser.vy
- Bonding curve trader contract
The main contract responsible for managing pUSD token operations on Ethereum mainnet.
Key State Variables:
ASSET
: The underlying asset address (e.g., WETH)Pool
: AAVE Pool V3 address for yield generationGOV
: Governance address for fee collectioncompass_evm
: Cross-chain bridge contract addressredemption_fee
: Fee charged on withdrawals (in basis points)total_supply
: Total amount of underlying asset deposited
Functions:
__init__(_compass_evm: address, _initial_asset: address, _pool: address, _aggregator: address, _exponent: uint256, _governance: address, _refund_wallet: address, _router02: address, _redepmtion_fee: uint256)
- Purpose: Constructor function that initializes the contract
- Parameters:
_compass_evm
: Cross-chain bridge contract address_initial_asset
: Underlying asset token address_pool
: AAVE Pool V3 address_aggregator
: Chainlink price aggregator address_exponent
: Price exponent for gas calculations_governance
: Governance address for fee collection_refund_wallet
: Wallet to receive gas fee refunds_router02
: Uniswap V3 router address_redepmtion_fee
: Redemption fee in basis points
- Security: Validates redemption fee is less than 100% (DENOMINATOR)
- Example Usage:
# Deploy with WETH as underlying asset
pusd_manager = PusdManager.deploy(
compass_evm=0x...,
_initial_asset=0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2, # WETH
_pool=0x...,
_aggregator=0x...,
_exponent=8,
_governance=0x...,
_refund_wallet=0x...,
_router02=0x...,
_redepmtion_fee=100 # 1% fee
)
deposit(recipient: bytes32, amount: uint256, path: Bytes[204] = b"", min_amount: uint256 = 0) -> uint256
- Purpose: Deposits underlying asset and mints pUSD tokens
- Parameters:
recipient
: Cross-chain recipient address (bytes32)amount
: Amount of underlying asset to depositpath
: Uniswap V3 swap path (optional)min_amount
: Minimum output amount for swaps (optional)
- Returns: Amount of pUSD tokens minted
- Security Features:
- Non-reentrant protection
- Validates amount > 0
- Handles both direct deposits and swaps
- Supports ETH/WETH conversion
- Example Usage:
# Direct WETH deposit
pusd_amount = pusd_manager.deposit(
recipient=0x1234...,
amount=1000000000000000000, # 1 WETH
value=1000000000000000000
)
# Swap USDC to WETH then deposit
pusd_amount = pusd_manager.deposit(
recipient=0x1234...,
amount=1000000, # 1 USDC
path=encode_path(USDC, WETH),
min_amount=990000000000000000 # 0.99 WETH minimum
)
- Purpose: Withdraws underlying asset by burning pUSD tokens
- Parameters:
sender
: Cross-chain sender address (bytes32)recipient
: Ethereum address to receive withdrawn assetsamount
: Amount of pUSD tokens to burnnonce
: Unique withdrawal nonce to prevent replay attacks
- Security Features:
- Paloma bridge authentication
- Nonce replay protection
- Redemption fee calculation
- Gas fee deduction
- Validates recipient != compass_evm
- Example Usage:
# Called by compass bridge
pusd_manager.withdraw(
sender=0x1234...,
recipient=0xabcd...,
amount=1000000000000000000, # 1 pUSD
nonce=12345
)
- Purpose: Updates the compass bridge contract address
- Parameters:
new_compass
: New compass contract address
- Security: Only callable by current compass contract when SLC is unavailable
- Example Usage:
pusd_manager.update_compass(0xnew_compass_address)
- Purpose: Updates the refund wallet address
- Parameters:
_new_refund_wallet
: New refund wallet address
- Security: Requires paloma bridge authentication
- Example Usage:
pusd_manager.update_refund_wallet(0xnew_refund_wallet)
- Purpose: Updates the redemption fee percentage
- Parameters:
_new_redemption_fee
: New redemption fee in basis points
- Security:
- Requires paloma bridge authentication
- Validates fee < 100% (DENOMINATOR)
- Example Usage:
pusd_manager.update_redemption_fee(200) # 2% fee
- Purpose: Sets the paloma identifier for cross-chain operations
- Security:
- Only callable by compass contract
- Can only be set once (paloma must be empty)
- Requires specific message data length
- Example Usage:
pusd_manager.set_paloma() # Called by compass with paloma data
Similar to the main pUSD manager but optimized for xDai network without price oracle dependencies.
Key Differences:
- No Chainlink price aggregator integration
- Simplified gas fee calculation (no price conversion)
- Direct WXDAI handling
Functions: Same as main pUSD manager except for simplified gas calculations in withdraw()
.
Connector contract that handles cross-chain pUSD operations and fee collection.
Key State Variables:
pusd_manager
: Address of the pUSD manager contractpusd
: pUSD token addresswithdraw_limit
: Minimum withdrawal amountgas_fee
: Gas fee in ETHservice_fee
: Service fee percentage
Functions:
__init__(_compass: address, _pusd_manager: address, _pusd: address, _withdraw_limit: uint256, _weth9: address, _refund_wallet: address, _gas_fee: uint256, _service_fee_collector: address, _service_fee: uint256)
- Purpose: Constructor for connector contract
- Parameters:
_compass
: Cross-chain bridge address_pusd_manager
: pUSD manager contract address_pusd
: pUSD token address_withdraw_limit
: Minimum withdrawal amount_weth9
: WETH token address_refund_wallet
: Gas fee refund wallet_gas_fee
: Gas fee amount_service_fee_collector
: Service fee collector address_service_fee
: Service fee percentage
- Example Usage:
connector = PusdConnector.deploy(
_compass=0x...,
_pusd_manager=pusd_manager.address,
_pusd=pusd_token.address,
_withdraw_limit=1000000000000000000, # 1 pUSD
_weth9=0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2,
_refund_wallet=0x...,
_gas_fee=10000000000000000, # 0.01 ETH
_service_fee_collector=0x...,
_service_fee=50000000000000000 # 5%
)
- Purpose: Purchases pUSD tokens with any supported asset
- Parameters:
path
: Uniswap V3 swap pathamount
: Amount of input tokenmin_amount
: Minimum output amount for swaps
- Security Features:
- Non-reentrant protection
- Gas fee deduction
- Service fee collection
- Supports ETH/WETH conversion
- Example Usage:
# Purchase pUSD with USDC
connector.purchase(
path=encode_path(USDC, WETH),
amount=1000000, # 1 USDC
min_amount=990000000000000000, # 0.99 WETH minimum
value=10000000000000000 # 0.01 ETH gas fee
)
- Purpose: Initiates cross-chain withdrawal of pUSD tokens
- Parameters:
amount
: Amount of pUSD to withdraw
- Security Features:
- Validates withdrawal limit
- Checks total supply availability
- Gas and service fee handling
- Example Usage:
connector.withdraw(
amount=1000000000000000000, # 1 pUSD
value=10000000000000000 # 0.01 ETH gas fee
)
Bonding curve trader contract for pUSD token trading.
Functions:
- Purpose: Purchases pUSD and sends to specified token on another chain
- Parameters:
to_token
: Token address on destination chainpath
: Swap path for input tokenamount
: Amount of input tokenmin_amount
: Minimum output amount
- Example Usage:
purchaser.purchase(
to_token=0x...,
path=encode_path(USDC, WETH),
amount=1000000,
min_amount=990000000000000000,
value=10000000000000000
)
- Purpose: Sells tokens and sends pUSD to another chain
- Parameters:
from_token
: Token to sellamount
: Amount to sell
- Example Usage:
purchaser.sell(
from_token=0x...,
amount=1000000000000000000,
value=10000000000000000
)
- Purpose: Purchases tokens using existing pUSD balance
- Parameters:
to_token
: Token address on destination chainpusd
: pUSD token addressamount
: Amount of pUSD to use
- Example Usage:
purchaser.purchase_by_pusd(
to_token=0x...,
pusd=pusd_token.address,
amount=1000000000000000000,
value=10000000000000000
)
- Governance: Only governance address can receive fees
- Compass Bridge: Cross-chain operations require compass authentication
- Paloma Verification: All cross-chain calls verify paloma identifier
- All external functions use
@nonreentrant
decorator - State changes occur before external calls where possible
- Amount validation (must be > 0)
- Address validation (recipient != compass_evm)
- Fee validation (redemption_fee < 100%)
- Nonce replay protection
- Efficient storage usage with immutable variables
- Minimal external calls
- Optimized math operations
To run tests, ensure you have the following installed:
-
Clone the Repository:
git clone https://github.com/VolumeFi/pusd-manager-vyper.git cd pusd-manager-vyper
-
Set Up Virtual Environment:
python3 -m venv venv source venv/bin/activate # On Windows: venv\Scripts\activate
-
Install Ape Framework:
pip install eth-ape
-
Compile Contracts:
ape compile
-
Run All Tests:
ape test
-
Run Tests with Verbose Output:
ape test -v
-
Run Specific Test File:
ape test tests/test_pusd_manager.py
-
Run Tests with Coverage:
ape test --coverage
-
Run Tests on Specific Network:
ape test --network ethereum:mainnet:alchemy
Create a tests/
directory with the following structure:
tests/
├── conftest.py # Test fixtures and setup
├── test_pusd_manager.py # Main pUSD manager tests
├── test_connector.py # Connector contract tests
└── test_purchaser.py # Purchaser contract tests
# tests/test_pusd_manager.py
import pytest
from ape import accounts, Contract
@pytest.fixture
def owner(accounts):
return accounts[0]
@pytest.fixture
def user(accounts):
return accounts[1]
@pytest.fixture
def pusd_manager(owner, project):
return owner.deploy(project.PusdManager,
_compass_evm="0x...",
_initial_asset="0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2",
_pool="0x...",
_aggregator="0x...",
_exponent=8,
_governance=owner.address,
_refund_wallet="0x...",
_router02="0x...",
_redepmtion_fee=100)
def test_deposit(pusd_manager, user):
"""Test pUSD deposit functionality"""
amount = 1000000000000000000 # 1 WETH
# User deposits WETH
tx = pusd_manager.deposit(
recipient=b"0x1234",
amount=amount,
sender=user,
value=amount
)
# Verify deposit event
assert tx.events[0].sender == user.address
assert tx.events[0].amount == amount
def test_withdraw(pusd_manager, owner):
"""Test pUSD withdrawal functionality"""
# Mock compass call
pusd_manager.withdraw(
sender=b"0x1234",
recipient=owner.address,
amount=1000000000000000000,
nonce=1,
sender=owner
)
-
Configure Environment:
export PRIVATE_KEY="your_private_key" export ALCHEMY_API_KEY="your_alchemy_key"
-
Deploy Contracts:
ape run scripts/deploy.py --network ethereum:mainnet:alchemy
ape run scripts/deploy.py --network ethereum:goerli:alchemy
We welcome contributions to enhance the pUSD Manager Vyper contract. To contribute:
- Fork the Repository: Click on the 'Fork' button at the top right corner of this page.
- Create a New Branch: Use a descriptive name for your branch.
- Make Your Changes: Implement your feature or fix.
- Add Tests: Ensure all new functionality has corresponding tests.
- Submit a Pull Request: Provide a clear description of your changes and the problem they solve.
Please ensure that your contributions adhere to our coding standards and include appropriate tests.
This project is licensed under the MIT License. See the LICENSE file for details.
We extend our gratitude to the VolumeFi community and all contributors who have supported the development of the pUSD Manager Vyper contract.
This README provides comprehensive documentation for security auditors, including detailed function descriptions, security considerations, usage examples, and testing instructions. For more detailed information about specific implementations, please refer to the contract source code.