Savings Module Integration
Integrate Parallel Savings Module to earn from your stablecoins
The Savings module provides a yield-bearing vault system built on the ERC4626 standard, allowing users to deposit Parallel stablecoins and earn interest through a configurable inflation rate mechanism.
These are simple ERC4626 contracts which do not invest the tokens deposited in it, but simply mint new tokens based on a rate defined by governance. This repo contains the contract implementation.
As such, apart from the savings module contract smart contract risk, there is no extra trust assumption between owning a stablecoin and owning a stablecoin in a staking contract to earn a yield from it.
Overview
Savings module contracts act as interest-bearing vaults where users can deposit their Parallel stablecoins and automatically earn yield over time. The system uses a sophisticated inflation rate mechanism that compounds interest continuously, providing predictable returns for depositors.
Key Features
ERC4626 Standard: Full compatibility with the industry-standard vault interface
Continuous Compounding: Interest accrues continuously based on a configurable rate
Governance-Controlled: Interest rates are managed by trusted addresses and governance
Pause Functionality: Emergency pause mechanism for security
Upgradeable: UUPS proxy pattern for future improvements
How It Works
Deposit: Users deposit Parallel stablecoins (eg. USDp) and receive vault shares (eg. sUSDp)
Interest Accrual: The vault continuously mints new tokens based on the inflation rate
Share Value Growth: As the total assets increase, each share becomes more valuable
Withdrawal: Users can redeem shares for the underlying assets plus accrued interest
Core Functions
Depositing Assets
Deposit Exact Amount (deposit
)
deposit
)function deposit(uint256 assets, address receiver)
external returns (uint256 shares);
Parameters:
assets
: Exact amount of underlying tokens to depositreceiver
: Address that will receive the vault shares
Returns:
shares
: Number of vault shares minted to the receiver
Prerequisites:
Approve the Savings module contract to spend your underlying tokens
Contract must not be paused
Mint Exact Shares (mint
)
mint
)function mint(uint256 shares, address receiver)
external returns (uint256 assets);
Parameters:
shares
: Exact number of vault shares to mintreceiver
: Address that will receive the vault shares
Returns:
assets
: Amount of underlying tokens required for the deposit
Use Case: When you want a specific number of shares rather than a specific asset amount
Withdrawing Assets
Withdraw Exact Amount (withdraw
)
withdraw
)function withdraw(
uint256 assets,
address receiver,
address owner
) external returns (uint256 shares);
Parameters:
assets
: Exact amount of underlying tokens to withdrawreceiver
: Address that will receive the underlying tokensowner
: Address that owns the shares being redeemed
Returns:
shares
: Number of vault shares burned
Redeem Exact Shares (redeem
)
redeem
)function redeem(
uint256 shares,
address receiver,
address owner
) external returns (uint256 assets);
Parameters:
shares
: Exact number of vault shares to redeemreceiver
: Address that will receive the underlying tokensowner
: Address that owns the shares being redeemed
Returns:
assets
: Amount of underlying tokens received
View Functions
Get Total Assets (totalAssets
)
totalAssets
)function totalAssets() external view returns (uint256);
Returns the total amount of underlying assets held by the vault, including accrued interest.
Estimate Annual Percentage Yield (estimatedAPR
)
estimatedAPR
)The contract comes with a wrapper estimatedAPR
function which gives the estimated APY in base 18 for depositing in this contract.
A 1% APY for this function would correspond to a value of 10000000000000000.
function estimatedAPR() external view returns (uint256 apr);
Compute Updated Assets (computeUpdatedAssets
)
computeUpdatedAssets
)You can anticipate (assuming the inflation rate does not change) how much you'll earn for a period of time by depositing in the contract by calling the computeUpdatedAssets
function:
function computeUpdatedAssets(uint256 _totalAssets, uint256 exp)
external view returns (uint256);
Parameters:
_totalAssets
: Current total assets amountexp
: Time period in seconds
Returns:
Updated asset amount after the specified time period
Integration Patterns
Basic Deposit Flow
// 1. Get current yield information
uint256 currentAPY = savings.estimatedAPR(); // Note: function name is misleading, returns APY
// 2. Approve tokens
IERC20(underlyingAsset).approve(address(savings), depositAmount);
// 3. Deposit assets
uint256 shares = savings.deposit(depositAmount, msg.sender);
// 4. Track the deposit
emit Deposit(msg.sender, depositAmount, shares);
Withdrawal Flow
// 1. Check current share value
uint256 totalAssets = savings.totalAssets();
uint256 totalShares = savings.totalSupply();
uint256 shareValue = totalAssets * 1e18 / totalShares;
// 2. Calculate shares needed for desired amount
uint256 sharesNeeded = (desiredAmount * 1e18) / shareValue;
// 3. Redeem shares
uint256 assetsReceived = savings.redeem(sharesNeeded, msg.sender, msg.sender);
// 4. Track the withdrawal
emit Withdrawal(msg.sender, assetsReceived, sharesNeeded);
Monitoring Interest Accrual
// Track user's position over time
struct UserPosition {
uint256 shares;
uint256 depositTime;
uint256 lastCheckpoint;
}
function getUserYield(address user) external view returns (uint256) {
UserPosition memory position = userPositions[user];
uint256 currentAssets = savings.totalAssets();
uint256 currentShares = savings.totalSupply();
// Calculate current value of user's shares
uint256 currentValue = (position.shares * currentAssets) / currentShares;
// Calculate original deposit value (approximate)
uint256 originalValue = position.shares; // Assuming 1:1 at deposit
return currentValue - originalValue;
}
Rate modifications
The inflation rate in a Savings module contract is encoded by keepers whitelisted by the DAO. As such, it is non dilutive and does not vary as people deposit more capital or withdraw their assets.
Depending on the stablecoin and on the setup, governance may follow different update schedules. And the frequency of updates may vary from every week to every several months. Between two updates, depositors in Savings module contract are guaranteed to earn a fixed rate on their assets.
Last updated
Was this helpful?