Website · App · Docs · Contract Natspec
Apyx is the first dividend-backed stablecoin protocol, transforming preferred equity issued by Digital Asset Treasuries (DATs) into programmable, high-yield digital dollars. By bundling diversified preferred shares and leveraging protocol functionality, Apyx offers sustained double-digit yield with unprecedented transparency.
apxUSD is a synthetic dollar backed by DAT preferred shares, serving as the protocol's primary liquidity layer. apyUSD is the yield-bearing savings wrapper, accruing yield from the dividends paid by the underlying collateral.
Documentation
Contract Addresses (Ethereum Mainnet)
| Token | Address |
|---|---|
| apxUSD | 0x98A878b1Cd98131B271883B390f68D2c90674665 |
| apyUSD | 0x38EEb52F0771140d10c4E9A9a72349A329Fe8a6A |
X · Discord · Telegram · GitHub · Reddit · LinkedIn
Overview
The Apyx protocol consists of multiple interconnected contracts that enable stablecoin minting, yield distribution, and token locking mechanisms.
| Contract | Description |
|---|---|
| ApxUSD | The base ERC-20 stablecoin with supply cap, pause, and freeze functionality. Implements EIP-2612 permit for gasless approvals and uses the UUPS upgradeable pattern. |
| ApyUSD | An ERC-4626 yield-bearing vault that wraps apxUSD, allowing deposits to accrue yield from vesting distributions. |
| CommitToken | An async redeem vault inspired by ERC-7540 with a configurable cooldown period for unlocking. Implements deny list checking and can lock arbitrary ERC-20 tokens for use in off-chain points systems. See ERC-7540 note below. |
| UnlockToken | A CommitToken subclass that allows a vault to initiate redeem requests on behalf of users, enabling automated withdrawal flows. See ERC-7540 note below. |
| MinterV0 | Handles apxUSD minting via EIP-712 signed orders with rate limiting and AccessManager integration for delayed execution. |
| LinearVestV0 | A linear vesting contract that gradually releases yield to the vault over a configurable period. |
| YieldDistributor | Receives minting fees and deposits them to the vesting contract for gradual distribution. |
| AddressList | Provides centralized deny list management for compliance across all Apyx contracts. |
Architecture
The Apyx protocol consists of several interconnected systems. The following diagrams illustrate the key relationships and flows:
Minting Flow
A signed EIP-712 order must be submitted by a "Minter" (an m-of-n wallet). The MinterV0 contract validates the order and mints apxUSD after AccessManager delays. The beneficiary must be checked against the AddressList before minting completes.
flowchart TB
User[User] -->|"signs EIP-712 order"| Minter["Minter (m-of-n wallet)"]
Minter -->|"submits order"| MinterV0
MinterV0 -->|"checks role + delay"| AccessManager
MinterV0 -->|"checks beneficiary"| AddressList
MinterV0 -->|"mint()"| ApxUSD
AccessManager -.->|"manages mint permissions"| ApxUSD
Token Relationships
ApyUSD is an ERC-4626 vault that wraps apxUSD for yield-bearing deposits. Withdrawing from ApyUSD transfers the ApxUSD to the UnlockToken. The UnlockToken implements an async redemption flow inspired by ERC-7540. The UnlockToken allows ApyUSD to initiate redeem requests on behalf of users to start the unlocking period.
flowchart TB
ApxUSD[ApxUSD - ERC-20 Stablecoin]
ApyUSD[ApyUSD - ERC-4626 Vault]
UnlockToken[UnlockToken - Vault-Initiated Redeems]
AddressList[AddressList - Deny List]
AccessManager[AccessManager]
ApyUSD -->|"deposit/withdraw"| ApxUSD
ApyUSD -->|"initiates redeems"| UnlockToken
ApyUSD -->|"checks transfers"| AddressList
UnlockToken -->|"checks transfers"| AddressList
AccessManager -.->|"manages admin functions"| ApyUSD
Yield Distribution
When the underlying offchain collateral (preferred shares) pay dividends the dividends are minted as apxUSD to YieldDistributor. The YieldDistributor sits between the MinterV0 and the LinearVestV0 to decouple the two contracts and allows a yield operator to trigger deposits into the vesting contract.
flowchart TB
MinterV0 -->|"fees on mint"| YieldDistributor
YieldDistributor -->|"depositYield()"| LinearVestV0
LinearVestV0 -->|"pullVestedYield()"| ApyUSD
ApyUSD -->|"increases share value"| Depositors
Lock Tokens for Points
CommitToken is a standalone vault that locks any ERC-20 token with a configurable unlocking period. Users deposit tokens to receive non-transferable lock tokens, which can be used for off-chain points systems.
flowchart TB
User -->|"deposit(assets)"| CommitToken
CommitToken -->|"mints shares"| User
User -->|"requestRedeem(shares)"| CommitToken
CommitToken -->|"starts cooldown"| CooldownPeriod[Cooldown Period]
CooldownPeriod -->|"after delay"| User
User -->|"redeem()"| Assets[Original Assets]
ERC-7540 Note
CommitToken and UnlockToken implement a custom async redemption flow inspired by ERC-7540, but are NOT compliant with the ERC-7540 specification. They deviate from MUST requirements including: shares not removed from owner on request, preview functions not reverting, operator functionality not supported, and ERC-7575 share() method not implemented.
Installation
This project uses Foundry and Soldeer for dependency management.
# Clone the repository
git clone <repo-url>
cd evm-contracts
# Install dependencies
forge soldeer install
Development
Build
forge build
Or using the Justfile:
just build
Test
Run all tests:
forge test
Run with gas reporting:
forge test --gas-report
# or
just test-gas
Run with verbose output:
forge test -vvv
Code Coverage
forge coverage
# or
just coverage
Format Code
forge fmt
# or
just fmt
Testing
The test suite is organized in the test/ directory with the following structure:
- test/contracts/ - Tests organized by contract (ApxUSD, ApyUSD, CommitToken, MinterV0, Vesting, YieldDistributor)
- test/exts/ - Extension tests (ERC20FreezeableUpgradable)
- test/mocks/ - Mock contracts for testing
- test/utils/ - Test utilities (VmExt, Formatter, Errors)
- test/reports/ - Report (csv) generation tests
Each contract subdirectory contains a BaseTest.sol with shared setup and individual test files for specific functionality.
Dependencies
- OpenZeppelin Contracts Upgradeable v5.5.0
- OpenZeppelin Contracts v5.5.0
- Forge Standard Library v1.11.0
Resources
- Foundry Book
- OpenZeppelin Docs
- EIP-712: Typed structured data hashing and signing
- ERC-2612: Permit Extension for ERC-20
- ERC-7201: Namespaced Storage Layout
Contents
ICurveStableswapFactoryNG
Functions
asset_types
function asset_types(uint8 arg0) external view returns (string memory);
deploy_gauge
function deploy_gauge(address _pool) external returns (address);
deploy_plain_pool
function deploy_plain_pool(
string memory _name,
string memory _symbol,
address[] memory _coins,
uint256 _A,
uint256 _fee,
uint256 _offpeg_fee_multiplier,
uint256 _ma_exp_time,
uint256 _implementation_idx,
uint8[] memory _asset_types,
bytes4[] memory _method_ids,
address[] memory _oracles
) external returns (address);
deploy_metapool
function deploy_metapool(
address _base_pool,
string memory _name,
string memory _symbol,
address _coin,
uint256 _A,
uint256 _fee,
uint256 _offpeg_fee_multiplier,
uint256 _ma_exp_time,
uint256 _implementation_idx,
uint8 _asset_type,
bytes4 _method_id,
address _oracle
) external returns (address);
find_pool_for_coins
function find_pool_for_coins(address _from, address _to) external view returns (address);
find_pool_for_coins
function find_pool_for_coins(address _from, address _to, uint256 i) external view returns (address);
pool_count
function pool_count() external view returns (uint256);
pool_list
function pool_list(uint256 arg0) external view returns (address);
get_A
function get_A(address _pool) external view returns (uint256);
get_balances
function get_balances(address _pool) external view returns (uint256[] memory);
get_base_pool
function get_base_pool(address _pool) external view returns (address);
get_coin_indices
function get_coin_indices(address _pool, address _from, address _to) external view returns (int128, int128, bool);
get_coins
function get_coins(address _pool) external view returns (address[] memory);
get_decimals
function get_decimals(address _pool) external view returns (uint256[] memory);
get_fees
function get_fees(address _pool) external view returns (uint256, uint256);
get_gauge
function get_gauge(address _pool) external view returns (address);
get_implementation_address
function get_implementation_address(address _pool) external view returns (address);
get_meta_n_coins
function get_meta_n_coins(address _pool) external view returns (uint256, uint256);
get_metapool_rates
function get_metapool_rates(address _pool) external view returns (uint256[] memory);
get_n_coins
function get_n_coins(address _pool) external view returns (uint256);
get_pool_asset_types
function get_pool_asset_types(address _pool) external view returns (uint8[] memory);
get_underlying_balances
function get_underlying_balances(address _pool) external view returns (uint256[] memory);
get_underlying_coins
function get_underlying_coins(address _pool) external view returns (address[] memory);
get_underlying_decimals
function get_underlying_decimals(address _pool) external view returns (uint256[] memory);
is_meta
function is_meta(address _pool) external view returns (bool);
gauge_implementation
function gauge_implementation() external view returns (address);
math_implementation
function math_implementation() external view returns (address);
metapool_implementations
function metapool_implementations(uint256 arg0) external view returns (address);
pool_implementations
function pool_implementations(uint256 arg0) external view returns (address);
views_implementation
function views_implementation() external view returns (address);
Events
BasePoolAdded
event BasePoolAdded(address base_pool);
LiquidityGaugeDeployed
event LiquidityGaugeDeployed(address pool, address gauge);
MetaPoolDeployed
event MetaPoolDeployed(address coin, address base_pool, uint256 A, uint256 fee, address deployer);
PlainPoolDeployed
event PlainPoolDeployed(address[] coins, uint256 A, uint256 fee, address deployer);
ICurveStableswapNG
Functions
A
function A() external view returns (uint256);
A_precise
function A_precise() external view returns (uint256);
DOMAIN_SEPARATOR
function DOMAIN_SEPARATOR() external view returns (bytes32);
D_ma_time
function D_ma_time() external view returns (uint256);
D_oracle
function D_oracle() external view returns (uint256);
N_COINS
function N_COINS() external view returns (uint256);
add_liquidity
function add_liquidity(uint256[] memory _amounts, uint256 _min_mint_amount) external returns (uint256);
add_liquidity
function add_liquidity(uint256[] memory _amounts, uint256 _min_mint_amount, address _receiver)
external
returns (uint256);
admin_balances
function admin_balances(uint256 arg0) external view returns (uint256);
admin_fee
function admin_fee() external view returns (uint256);
allowance
function allowance(address arg0, address arg1) external view returns (uint256);
approve
function approve(address _spender, uint256 _value) external returns (bool);
balanceOf
function balanceOf(address arg0) external view returns (uint256);
balances
function balances(uint256 i) external view returns (uint256);
calc_token_amount
function calc_token_amount(uint256[] memory _amounts, bool _is_deposit) external view returns (uint256);
calc_withdraw_one_coin
function calc_withdraw_one_coin(uint256 _burn_amount, int128 i) external view returns (uint256);
coins
function coins(uint256 arg0) external view returns (address);
decimals
function decimals() external view returns (uint8);
dynamic_fee
function dynamic_fee(int128 i, int128 j) external view returns (uint256);
ema_price
function ema_price(uint256 i) external view returns (uint256);
exchange
function exchange(int128 i, int128 j, uint256 _dx, uint256 _min_dy) external returns (uint256);
exchange
function exchange(int128 i, int128 j, uint256 _dx, uint256 _min_dy, address _receiver) external returns (uint256);
exchange_received
function exchange_received(int128 i, int128 j, uint256 _dx, uint256 _min_dy) external returns (uint256);
exchange_received
function exchange_received(int128 i, int128 j, uint256 _dx, uint256 _min_dy, address _receiver)
external
returns (uint256);
fee
function fee() external view returns (uint256);
future_A
function future_A() external view returns (uint256);
future_A_time
function future_A_time() external view returns (uint256);
get_balances
function get_balances() external view returns (uint256[] memory);
get_dx
function get_dx(int128 i, int128 j, uint256 dy) external view returns (uint256);
get_dy
function get_dy(int128 i, int128 j, uint256 dx) external view returns (uint256);
get_p
function get_p(uint256 i) external view returns (uint256);
get_virtual_price
function get_virtual_price() external view returns (uint256);
initial_A
function initial_A() external view returns (uint256);
initial_A_time
function initial_A_time() external view returns (uint256);
last_price
function last_price(uint256 i) external view returns (uint256);
ma_exp_time
function ma_exp_time() external view returns (uint256);
ma_last_time
function ma_last_time() external view returns (uint256);
name
function name() external view returns (string memory);
nonces
function nonces(address arg0) external view returns (uint256);
offpeg_fee_multiplier
function offpeg_fee_multiplier() external view returns (uint256);
permit
function permit(
address _owner,
address _spender,
uint256 _value,
uint256 _deadline,
uint8 _v,
bytes32 _r,
bytes32 _s
) external returns (bool);
price_oracle
function price_oracle(uint256 i) external view returns (uint256);
ramp_A
function ramp_A(uint256 _future_A, uint256 _future_time) external;
remove_liquidity
function remove_liquidity(uint256 _burn_amount, uint256[] memory _min_amounts) external returns (uint256[] memory);
remove_liquidity
function remove_liquidity(uint256 _burn_amount, uint256[] memory _min_amounts, address _receiver)
external
returns (uint256[] memory);
remove_liquidity
function remove_liquidity(
uint256 _burn_amount,
uint256[] memory _min_amounts,
address _receiver,
bool _claim_admin_fees
) external returns (uint256[] memory);
remove_liquidity_imbalance
function remove_liquidity_imbalance(uint256[] memory _amounts, uint256 _max_burn_amount) external returns (uint256);
remove_liquidity_imbalance
function remove_liquidity_imbalance(uint256[] memory _amounts, uint256 _max_burn_amount, address _receiver)
external
returns (uint256);
remove_liquidity_one_coin
function remove_liquidity_one_coin(uint256 _burn_amount, int128 i, uint256 _min_received) external returns (uint256);
remove_liquidity_one_coin
function remove_liquidity_one_coin(uint256 _burn_amount, int128 i, uint256 _min_received, address _receiver)
external
returns (uint256);
salt
function salt() external view returns (bytes32);
set_ma_exp_time
function set_ma_exp_time(uint256 _ma_exp_time, uint256 _D_ma_time) external;
set_new_fee
function set_new_fee(uint256 _new_fee, uint256 _new_offpeg_fee_multiplier) external;
stop_ramp_A
function stop_ramp_A() external;
stored_rates
function stored_rates() external view returns (uint256[] memory);
symbol
function symbol() external view returns (string memory);
totalSupply
function totalSupply() external view returns (uint256);
transfer
function transfer(address _to, uint256 _value) external returns (bool);
transferFrom
function transferFrom(address _from, address _to, uint256 _value) external returns (bool);
version
function version() external view returns (string memory);
withdraw_admin_fees
function withdraw_admin_fees() external;
Events
AddLiquidity
event AddLiquidity(
address indexed provider, uint256[] token_amounts, uint256[] fees, uint256 invariant, uint256 token_supply
);
ApplyNewFee
event ApplyNewFee(uint256 fee, uint256 offpeg_fee_multiplier);
Approval
event Approval(address indexed owner, address indexed spender, uint256 value);
RampA
event RampA(uint256 old_A, uint256 new_A, uint256 initial_time, uint256 future_time);
RemoveLiquidity
event RemoveLiquidity(address indexed provider, uint256[] token_amounts, uint256[] fees, uint256 token_supply);
RemoveLiquidityImbalance
event RemoveLiquidityImbalance(
address indexed provider, uint256[] token_amounts, uint256[] fees, uint256 invariant, uint256 token_supply
);
RemoveLiquidityOne
event RemoveLiquidityOne(
address indexed provider, int128 token_id, uint256 token_amount, uint256 coin_amount, uint256 token_supply
);
SetNewMATime
event SetNewMATime(uint256 ma_exp_time, uint256 D_ma_time);
StopRampA
event StopRampA(uint256 A, uint256 t);
TokenExchange
event TokenExchange(
address indexed buyer, int128 sold_id, uint256 tokens_sold, int128 bought_id, uint256 tokens_bought
);
TokenExchangeUnderlying
event TokenExchangeUnderlying(
address indexed buyer, int128 sold_id, uint256 tokens_sold, int128 bought_id, uint256 tokens_bought
);
Transfer
event Transfer(address indexed sender, address indexed receiver, uint256 value);
ICurveTwocryptoFactoryNG
Functions
accept_transfer_ownership
function accept_transfer_ownership() external;
admin
function admin() external view returns (address);
commit_transfer_ownership
function commit_transfer_ownership(address _addr) external;
deploy_gauge
function deploy_gauge(address _pool) external returns (address);
deploy_pool
function deploy_pool(
string memory _name,
string memory _symbol,
address[2] memory _coins,
uint256 implementation_id,
uint256 A,
uint256 gamma,
uint256 mid_fee,
uint256 out_fee,
uint256 fee_gamma,
uint256 allowed_extra_profit,
uint256 adjustment_step,
uint256 ma_exp_time,
uint256 initial_price
) external returns (address);
fee_receiver
function fee_receiver() external view returns (address);
find_pool_for_coins
function find_pool_for_coins(address _from, address _to) external view returns (address);
find_pool_for_coins
function find_pool_for_coins(address _from, address _to, uint256 i) external view returns (address);
future_admin
function future_admin() external view returns (address);
gauge_implementation
function gauge_implementation() external view returns (address);
get_balances
function get_balances(address _pool) external view returns (uint256[2] memory);
get_coin_indices
function get_coin_indices(address _pool, address _from, address _to) external view returns (uint256, uint256);
get_coins
function get_coins(address _pool) external view returns (address[2] memory);
get_decimals
function get_decimals(address _pool) external view returns (uint256[2] memory);
get_gauge
function get_gauge(address _pool) external view returns (address);
get_market_counts
function get_market_counts(address coin_a, address coin_b) external view returns (uint256);
initialise_ownership
function initialise_ownership(address _fee_receiver, address _admin) external;
math_implementation
function math_implementation() external view returns (address);
pool_count
function pool_count() external view returns (uint256);
pool_implementations
function pool_implementations(uint256 arg0) external view returns (address);
pool_list
function pool_list(uint256 arg0) external view returns (address);
set_fee_receiver
function set_fee_receiver(address _fee_receiver) external;
set_gauge_implementation
function set_gauge_implementation(address _gauge_implementation) external;
set_math_implementation
function set_math_implementation(address _math_implementation) external;
set_pool_implementation
function set_pool_implementation(address _pool_implementation, uint256 _implementation_index) external;
set_views_implementation
function set_views_implementation(address _views_implementation) external;
views_implementation
function views_implementation() external view returns (address);
Events
LiquidityGaugeDeployed
event LiquidityGaugeDeployed(address pool, address gauge);
TransferOwnership
event TransferOwnership(address _old_owner, address _new_owner);
TwocryptoPoolDeployed
event TwocryptoPoolDeployed(
address pool,
string name,
string symbol,
address[2] coins,
address math,
bytes32 salt,
uint256[2] precisions,
uint256 packed_A_gamma,
uint256 packed_fee_params,
uint256 packed_rebalancing_params,
uint256 packed_prices,
address deployer
);
UpdateFeeReceiver
event UpdateFeeReceiver(address _old_fee_receiver, address _new_fee_receiver);
UpdateGaugeImplementation
event UpdateGaugeImplementation(address _old_gauge_implementation, address _new_gauge_implementation);
UpdateMathImplementation
event UpdateMathImplementation(address _old_math_implementation, address _new_math_implementation);
UpdatePoolImplementation
event UpdatePoolImplementation(
uint256 _implemention_id, address _old_pool_implementation, address _new_pool_implementation
);
UpdateViewsImplementation
event UpdateViewsImplementation(address _old_views_implementation, address _new_views_implementation);
ICurveTwocryptoNG
Functions
A
function A() external view returns (uint256);
ADMIN_FEE
function ADMIN_FEE() external view returns (uint256);
D
function D() external view returns (uint256);
DOMAIN_SEPARATOR
function DOMAIN_SEPARATOR() external view returns (bytes32);
MATH
function MATH() external view returns (address);
add_liquidity
function add_liquidity(uint256[2] memory amounts, uint256 min_mint_amount) external returns (uint256);
add_liquidity
function add_liquidity(uint256[2] memory amounts, uint256 min_mint_amount, address receiver)
external
returns (uint256);
adjustment_step
function adjustment_step() external view returns (uint256);
admin
function admin() external view returns (address);
allowance
function allowance(address arg0, address arg1) external view returns (uint256);
allowed_extra_profit
function allowed_extra_profit() external view returns (uint256);
apply_new_parameters
function apply_new_parameters(
uint256 _new_mid_fee,
uint256 _new_out_fee,
uint256 _new_fee_gamma,
uint256 _new_allowed_extra_profit,
uint256 _new_adjustment_step,
uint256 _new_ma_time
) external;
approve
function approve(address _spender, uint256 _value) external returns (bool);
balanceOf
function balanceOf(address arg0) external view returns (uint256);
balances
function balances(uint256 arg0) external view returns (uint256);
calc_token_amount
function calc_token_amount(uint256[2] memory amounts, bool deposit) external view returns (uint256);
calc_token_fee
function calc_token_fee(uint256[2] memory amounts, uint256[2] memory xp) external view returns (uint256);
calc_withdraw_one_coin
function calc_withdraw_one_coin(uint256 token_amount, uint256 i) external view returns (uint256);
coins
function coins(uint256 arg0) external view returns (address);
decimals
function decimals() external view returns (uint8);
exchange
function exchange(uint256 i, uint256 j, uint256 dx, uint256 min_dy) external returns (uint256);
exchange
function exchange(uint256 i, uint256 j, uint256 dx, uint256 min_dy, address receiver) external returns (uint256);
exchange_received
function exchange_received(uint256 i, uint256 j, uint256 dx, uint256 min_dy) external returns (uint256);
exchange_received
function exchange_received(uint256 i, uint256 j, uint256 dx, uint256 min_dy, address receiver)
external
returns (uint256);
factory
function factory() external view returns (address);
fee
function fee() external view returns (uint256);
fee_calc
function fee_calc(uint256[2] memory xp) external view returns (uint256);
fee_gamma
function fee_gamma() external view returns (uint256);
fee_receiver
function fee_receiver() external view returns (address);
future_A_gamma
function future_A_gamma() external view returns (uint256);
future_A_gamma_time
function future_A_gamma_time() external view returns (uint256);
gamma
function gamma() external view returns (uint256);
get_dx
function get_dx(uint256 i, uint256 j, uint256 dy) external view returns (uint256);
get_dy
function get_dy(uint256 i, uint256 j, uint256 dx) external view returns (uint256);
get_virtual_price
function get_virtual_price() external view returns (uint256);
initial_A_gamma
function initial_A_gamma() external view returns (uint256);
initial_A_gamma_time
function initial_A_gamma_time() external view returns (uint256);
last_prices
function last_prices() external view returns (uint256);
last_timestamp
function last_timestamp() external view returns (uint256);
lp_price
function lp_price() external view returns (uint256);
ma_time
function ma_time() external view returns (uint256);
mid_fee
function mid_fee() external view returns (uint256);
name
function name() external view returns (string memory);
nonces
function nonces(address arg0) external view returns (uint256);
out_fee
function out_fee() external view returns (uint256);
packed_fee_params
function packed_fee_params() external view returns (uint256);
packed_rebalancing_params
function packed_rebalancing_params() external view returns (uint256);
permit
function permit(
address _owner,
address _spender,
uint256 _value,
uint256 _deadline,
uint8 _v,
bytes32 _r,
bytes32 _s
) external returns (bool);
precisions
function precisions() external view returns (uint256[2] memory);
price_oracle
function price_oracle() external view returns (uint256);
price_scale
function price_scale() external view returns (uint256);
ramp_A_gamma
function ramp_A_gamma(uint256 future_A, uint256 future_gamma, uint256 future_time) external;
remove_liquidity
function remove_liquidity(uint256 _amount, uint256[2] memory min_amounts) external returns (uint256[2] memory);
remove_liquidity
function remove_liquidity(uint256 _amount, uint256[2] memory min_amounts, address receiver)
external
returns (uint256[2] memory);
remove_liquidity_one_coin
function remove_liquidity_one_coin(uint256 token_amount, uint256 i, uint256 min_amount) external returns (uint256);
remove_liquidity_one_coin
function remove_liquidity_one_coin(uint256 token_amount, uint256 i, uint256 min_amount, address receiver)
external
returns (uint256);
salt
function salt() external view returns (bytes32);
stop_ramp_A_gamma
function stop_ramp_A_gamma() external;
symbol
function symbol() external view returns (string memory);
totalSupply
function totalSupply() external view returns (uint256);
transfer
function transfer(address _to, uint256 _value) external returns (bool);
transferFrom
function transferFrom(address _from, address _to, uint256 _value) external returns (bool);
version
function version() external view returns (string memory);
virtual_price
function virtual_price() external view returns (uint256);
xcp_profit
function xcp_profit() external view returns (uint256);
xcp_profit_a
function xcp_profit_a() external view returns (uint256);
Events
AddLiquidity
event AddLiquidity(
address indexed provider,
uint256[2] token_amounts,
uint256 fee,
uint256 token_supply,
uint256 packed_price_scale
);
Approval
event Approval(address indexed owner, address indexed spender, uint256 value);
ClaimAdminFee
event ClaimAdminFee(address indexed admin, uint256[2] tokens);
NewParameters
event NewParameters(
uint256 mid_fee,
uint256 out_fee,
uint256 fee_gamma,
uint256 allowed_extra_profit,
uint256 adjustment_step,
uint256 ma_time
);
RampAgamma
event RampAgamma(
uint256 initial_A,
uint256 future_A,
uint256 initial_gamma,
uint256 future_gamma,
uint256 initial_time,
uint256 future_time
);
RemoveLiquidity
event RemoveLiquidity(address indexed provider, uint256[2] token_amounts, uint256 token_supply);
RemoveLiquidityOne
event RemoveLiquidityOne(
address indexed provider,
uint256 token_amount,
uint256 coin_index,
uint256 coin_amount,
uint256 approx_fee,
uint256 packed_price_scale
);
StopRampA
event StopRampA(uint256 current_A, uint256 current_gamma, uint256 time);
TokenExchange
event TokenExchange(
address indexed buyer,
uint256 sold_id,
uint256 tokens_sold,
uint256 bought_id,
uint256 tokens_bought,
uint256 fee,
uint256 packed_price_scale
);
Transfer
event Transfer(address indexed sender, address indexed receiver, uint256 value);
Contents
ApxUSDDeployer
Inherits: AccessManaged, Deployer
Title: ApxUSDDeployer
Deploys ApxUSD (implementation + proxy) and initializes in a single transaction
Non-upgradable; deploy is restricted via AccessManager. Init params are set in the constructor.
State Variables
name
Token name for the deployed ApxUSD (e.g. "Apyx USD")
string public name
symbol
Token symbol for the deployed ApxUSD (e.g. "apxUSD")
string public symbol
denyList
Deny list (AddressList) for the deployed ApxUSD
address public denyList
supplyCap
Maximum total supply for the deployed ApxUSD (e.g. 1_000_000e18)
uint256 public supplyCap
Functions
constructor
Sets the AccessManager authority and ApxUSD init params used by deploy()
constructor(string memory _name, string memory _symbol, address _authority, address _denyList, uint256 _supplyCap)
AccessManaged(_authority);
Parameters
| Name | Type | Description |
|---|---|---|
_name | string | Token name for the deployed ApxUSD (e.g. "Apyx USD") |
_symbol | string | Token symbol for the deployed ApxUSD (e.g. "apxUSD") |
_authority | address | Address of the AccessManager contract (used for this deployer and for each deployed ApxUSD) |
_denyList | address | |
_supplyCap | uint256 | Maximum total supply for the deployed ApxUSD (e.g. 1_000_000e18) |
deploy
Deploys ApxUSD implementation, proxy, and initializes in one transaction using constructor params
Only callable through AccessManager (restricted)
function deploy() external restricted returns (address proxy);
Returns
| Name | Type | Description |
|---|---|---|
proxy | address | The address of the deployed ApxUSD proxy (use this as the stablecoin address) |
ApyUSDDeployer
Inherits: AccessManaged, Deployer, ERC1271Delegated, EInsufficientBalance
Title: ApyUSDDeployer
Deploys ApyUSD (implementation + proxy), initializes, deposits deployer's ApxUSD, and sends shares to beneficiary
Deploy is restricted via AccessManager. Requires deployer ApxUSD balance > 10_000e18 before deploying. Implements ERC-1271 via ERC1271Delegated so it can receive minted ApxUSD when MinterV0 supports contract beneficiaries.
State Variables
MIN_APXUSD_BALANCE
Minimum ApxUSD balance (in wei, 18 decimals) required on the deployer to call deploy()
uint256 public constant MIN_APXUSD_BALANCE = 10_000e18
name
Token name for the deployed ApyUSD (e.g. "Apyx Yield USD")
string public name
symbol
Token symbol for the deployed ApyUSD (e.g. "apyUSD")
string public symbol
asset
Underlying asset (ApxUSD) address for the deployed vault
address public asset
denyList
Deny list (AddressList) for the deployed ApyUSD
address public denyList
beneficiary
Recipient of ApyUSD shares after the initial deposit
address public beneficiary
Functions
constructor
Sets the AccessManager authority and ApyUSD init params used by deploy()
constructor(
address _authority,
string memory _name,
string memory _symbol,
address _asset,
address _denyList,
address _beneficiary,
address _signer
) AccessManaged(_authority) ERC1271Delegated(_signer);
Parameters
| Name | Type | Description |
|---|---|---|
_authority | address | Address of the AccessManager contract |
_name | string | Token name for the deployed ApyUSD (e.g. "Apyx Yield USD") |
_symbol | string | Token symbol for the deployed ApyUSD (e.g. "apyUSD") |
_asset | address | Address of the ApxUSD (underlying asset) contract |
_denyList | address | Address of the AddressList (deny list) contract |
_beneficiary | address | Recipient of ApyUSD shares after the initial deposit |
_signer | address |
deploy
Deploys ApyUSD, deposits deployer's ApxUSD, and sends resulting shares to beneficiary
Only callable through AccessManager (restricted). Reverts if deployer ApxUSD balance <= 10_000e18.
function deploy() external restricted returns (address proxy);
Returns
| Name | Type | Description |
|---|---|---|
proxy | address | The address of the deployed ApyUSD proxy |
Deployer
Title: Deployer
Interface for deployer contracts that deploy a proxy and emit on deployment
Functions
deploy
Deploys a proxy (and implementation if applicable), initializing in one transaction
function deploy() external returns (address proxy);
Returns
| Name | Type | Description |
|---|---|---|
proxy | address | The address of the deployed proxy |
Events
Deployed
Emitted when a new proxy is deployed
event Deployed(address indexed proxy, address indexed implementation);
Parameters
| Name | Type | Description |
|---|---|---|
proxy | address | The address of the deployed proxy |
implementation | address | The address of the implementation contract |
Contents
- EAddressNotSet
- EDenied
- EInsufficientBalance
- EInvalidAddress
- EInvalidAmount
- EInvalidCaller
- ENotSupported
- ESlippageExceeded
- ESupplyCapped
EAddressNotSet
Title: EAddressNotSet
Interface for the AddressNotSet error
Errors
AddressNotSet
Error thrown when a required address is not set (zero address)
error AddressNotSet(string name);
Parameters
| Name | Type | Description |
|---|---|---|
name | string | The name of the address parameter that is not set |
EDenied
Title: EDenied
Interface for the Denied error
Errors
Denied
Error thrown when trying to deposit/receive shares while on deny list
error Denied(address denied);
Parameters
| Name | Type | Description |
|---|---|---|
denied | address | The address that was denied |
EInsufficientBalance
Title: EInsufficientBalance
Interface for the InsufficientBalance error
Errors
InsufficientBalance
Error thrown when balance is insufficient for operation
error InsufficientBalance(address sender, uint256 balance, uint256 needed);
EInvalidAddress
Title: EInvalidAddress
Interface for the InvalidAddress error
Errors
InvalidAddress
Error thrown when a zero address is provided where it's not allowed
error InvalidAddress(string param);
EInvalidAmount
Title: EInvalidAmount
Interface for the InvalidAddress error
Errors
InvalidAmount
Error thrown when a zero address is provided where it's not allowed
error InvalidAmount(string param, uint256 amount);
EInvalidCaller
Title: EInvalidCaller
Interface for the InvalidCaller error
Errors
InvalidCaller
Error thrown when the caller is invalid
error InvalidCaller();
ENotSupported
Title: ENotSupported
Interface for the NotSupported error
Errors
NotSupported
Error thrown when a function is not supported
error NotSupported();
ESlippageExceeded
Title: ESlippageExceeded
Interface for the SlippageExceeded error
Errors
SlippageExceeded
Error thrown when the output of a redeem operation is below the minimum specified
error SlippageExceeded(uint256 reserveAmount, uint256 minReserveAssetOut);
Parameters
| Name | Type | Description |
|---|---|---|
reserveAmount | uint256 | The actual reserve amount that would be received |
minReserveAssetOut | uint256 | The minimum reserve amount required |
ESupplyCapped
Title: ESupplyCapped
Interface for supply cap related errors
Errors
SupplyCapExceeded
Error thrown when minting would exceed the supply cap
error SupplyCapExceeded(uint256 requestedAmount, uint256 availableCapacity);
InvalidSupplyCap
Error thrown when setting an invalid supply cap
error InvalidSupplyCap();
Contents
ERC1271Delegated
Inherits: IERC1271, EInvalidAddress
Title: ERC1271Delegated
Abstract contract that implements ERC-1271 by delegating signature validation to a stored delegate
Inheriting contracts set the delegate in the constructor. Uses OpenZeppelin's SignatureChecker so the delegate may be an EOA (ECDSA) or a contract (ERC-1271). See EIP-1271 and OpenZeppelin SignatureChecker documentation.
State Variables
signingDelegate
Address that is allowed to sign on behalf of this contract (e.g. Foundation multisig)
address public signingDelegate
_ERC1271_MAGIC
ERC-1271 magic value returned when the signature is valid
bytes4 private constant _ERC1271_MAGIC = IERC1271.isValidSignature.selector
_ERC1271_INVALID
Value returned when the signature is invalid (per EIP-1271)
bytes4 private constant _ERC1271_INVALID = 0xffffffff
Functions
constructor
Sets the signature delegate
constructor(address _signingDelegate) ;
Parameters
| Name | Type | Description |
|---|---|---|
_signingDelegate | address | Address that may sign on behalf of this contract |
isValidSignature
Validates a signature by delegating to the stored delegate via SignatureChecker
function isValidSignature(bytes32 hash, bytes calldata signature)
public
view
virtual
override
returns (bytes4 magicValue);
Parameters
| Name | Type | Description |
|---|---|---|
hash | bytes32 | Hash of the data that was signed |
signature | bytes | Signature bytes to validate |
Returns
| Name | Type | Description |
|---|---|---|
magicValue | bytes4 | ERC-1271 magic value (0x1626ba7e) if valid, 0xffffffff if invalid |
ERC20DenyListUpgradable
Inherits: Initializable, ERC20Upgradeable, EInvalidAddress, EDenied
State Variables
DENYLISTED_STORAGE_LOC
bytes32 private constant DENYLISTED_STORAGE_LOC =
0xde333b8ffad3aee9c87bb17db9ab84f10634c83b51f5022e3b2d7da89a012200
Functions
_getDenyListStorage
function _getDenyListStorage() internal pure returns (DenyListStorage storage $);
__ERC20DenyListedUpgradable_init
function __ERC20DenyListedUpgradable_init(IAddressList initialDenyList) internal onlyInitializing;
_isDenied
function _isDenied(address user) internal view returns (bool);
_revertIfDenied
function _revertIfDenied(address user) internal view;
checkNotDenied
modifier checkNotDenied(address user) ;
_update
Overrides the default ERC20 _update to enforce deny list checking
function _update(address from, address to, uint256 value) internal virtual override;
denyList
function denyList() public view returns (IAddressList);
_setDenyList
function _setDenyList(IAddressList newDenyList) internal;
Events
DenyListUpdated
Emitted when the deny list contract is updated
event DenyListUpdated(address indexed oldDenyList, address indexed newDenyList);
Parameters
| Name | Type | Description |
|---|---|---|
oldDenyList | address | Previous deny list contract address |
newDenyList | address | New deny list contract address |
Structs
DenyListStorage
Note: storage-location: erc7201:apyx.storage.DenyListed
struct DenyListStorage {
/// @notice Reference to the AddressList contract for deny list checking
IAddressList _denyList;
}
ERC20FreezeableUpgradable
Inherits: Initializable, ERC20Upgradeable
State Variables
FREEZEABLE_STORAGE_LOC
bytes32 private constant FREEZEABLE_STORAGE_LOC =
0xe66b3d99be4f71ea7aa9cf2bc9a8a4827bbe4f718fcfa5d183e05f8945211500
Functions
_getFreezeableStorage
function _getFreezeableStorage() private pure returns (FreezeableStorage storage $);
isFrozen
Allows for checking if an address is frozen
function isFrozen(address target) public view returns (bool);
Parameters
| Name | Type | Description |
|---|---|---|
target | address | The address to check |
Returns
| Name | Type | Description |
|---|---|---|
<none> | bool | bool True if the address is frozen |
_freeze
Freezes an address, stopping transfers to or from the address
Emits Frozen(target)
Reverts with ZeroAddress if target is address(0)
Note: Frozen addresses cannot burn tokens as burning involves transferring to address(0)
function _freeze(address target) internal virtual;
Parameters
| Name | Type | Description |
|---|---|---|
target | address | The address to freeze |
_unfreeze
Unfreezes an address, allowing transfers to or from the address
Emits Unfrozen(target)
function _unfreeze(address target) internal virtual;
Parameters
| Name | Type | Description |
|---|---|---|
target | address | The address to unfreeze |
_update
Overrides the default ERC20 _update to enforce freezing
Note: This prevents frozen addresses from burning tokens (burning = transfer to address(0))
Note: This prevents minting to frozen addresses (minting = transfer from address(0))
function _update(address from, address to, uint256 value) internal virtual override;
Events
Frozen
Emitted when an address is frozen.
event Frozen(address target);
Unfrozen
Emitted when an address is unfrozen.
event Unfrozen(address target);
Errors
FromFrozen
The transfer failed because the address transferring from is frozen.
error FromFrozen();
ToFrozen
The transfer failed because the address transferring to is frozen.
error ToFrozen();
ZeroAddress
Cannot freeze the zero address.
error ZeroAddress();
Structs
FreezeableStorage
Note: storage-location: erc7201:apyx.storage.Freezeable
struct FreezeableStorage {
mapping(address => bool) _frozen;
}
Contents
IAddressList
Title: IAddressList
Interface for central address list management in the Apyx protocol
Provides a single source of truth for blocked/allowed addresses across all Apyx contracts
Functions
add
Adds an address to the list
function add(address user) external;
Parameters
| Name | Type | Description |
|---|---|---|
user | address | Address to add |
remove
Removes an address from the list
function remove(address user) external;
Parameters
| Name | Type | Description |
|---|---|---|
user | address | Address to remove |
contains
Checks if an address is in the list
function contains(address user) external view returns (bool);
Parameters
| Name | Type | Description |
|---|---|---|
user | address | Address to check |
Returns
| Name | Type | Description |
|---|---|---|
<none> | bool | True if address is in the list, false otherwise |
length
Returns the number of addresses in the list
function length() external view returns (uint256);
Returns
| Name | Type | Description |
|---|---|---|
<none> | uint256 | Number of addresses |
at
Returns the address at the given index
function at(uint256 index) external view returns (address);
Parameters
| Name | Type | Description |
|---|---|---|
index | uint256 | Index of the address to retrieve |
Returns
| Name | Type | Description |
|---|---|---|
<none> | address | Address at the given index |
Events
Added
Emitted when an address is added to the list
event Added(address indexed user);
Parameters
| Name | Type | Description |
|---|---|---|
user | address | Address that was added |
Removed
Emitted when an address is removed from the list
event Removed(address indexed user);
Parameters
| Name | Type | Description |
|---|---|---|
user | address | Address that was removed |
IApyUSD
Inherits: EAddressNotSet, EDenied
Title: IApyUSD
Interface for apyUSD ERC4626 synchronous tokenized vault
Defines events for the sync vault implementation
Events
UnlockTokenUpdated
Emitted when the CommitToken contract is updated
event UnlockTokenUpdated(address indexed oldUnlockToken, address indexed newUnlockToken);
Parameters
| Name | Type | Description |
|---|---|---|
oldUnlockToken | address | Previous CommitToken contract address |
newUnlockToken | address | New CommitToken contract address |
UnlockTokenDepositError
Emitted when the deposit to UnlockToken fails
event UnlockTokenDepositError(uint256 assets, uint256 unlockTokenShares);
Parameters
| Name | Type | Description |
|---|---|---|
assets | uint256 | Amount of assets deposited |
unlockTokenShares | uint256 | Amount of unlockToken shares received |
VestingUpdated
Emitted when the Vesting contract is updated
event VestingUpdated(address indexed oldVesting, address indexed newVesting);
Parameters
| Name | Type | Description |
|---|---|---|
oldVesting | address | Previous Vesting contract address |
newVesting | address | New Vesting contract address |
UnlockingFeeUpdated
Emitted when the unlocking fee is updated
event UnlockingFeeUpdated(uint256 oldFee, uint256 newFee);
Parameters
| Name | Type | Description |
|---|---|---|
oldFee | uint256 | Previous unlocking fee |
newFee | uint256 | New unlocking fee |
FeeWalletUpdated
Emitted when the fee wallet is updated
event FeeWalletUpdated(address indexed oldFeeWallet, address indexed newFeeWallet);
Parameters
| Name | Type | Description |
|---|---|---|
oldFeeWallet | address | Previous fee wallet address |
newFeeWallet | address | New fee wallet address |
Errors
UnlockTokenError
Error thrown when the deposit to UnlockToken fails
error UnlockTokenError(string reason);
Parameters
| Name | Type | Description |
|---|---|---|
reason | string | Reason for the error |
SlippageExceeded
Error thrown when slippage protection is violated
error SlippageExceeded(uint256 expected, uint256 actual);
Parameters
| Name | Type | Description |
|---|---|---|
expected | uint256 | Expected amount |
actual | uint256 | Actual amount |
FeeExceedsMax
Error thrown when fee exceeds maximum allowed
error FeeExceedsMax(uint256 fee);
Parameters
| Name | Type | Description |
|---|---|---|
fee | uint256 | The fee that was attempted to be set |
ICommitToken
Inherits: IERC7540Redeem, EDenied, EInvalidAddress, EInvalidAmount, ENotSupported, EInvalidCaller, EInsufficientBalance, ESupplyCapped
Functions
requestWithdraw
Request an asynchronous withdrawal of assets
function requestWithdraw(uint256 assets, address controller, address owner) external returns (uint256 requestId);
Parameters
| Name | Type | Description |
|---|---|---|
assets | uint256 | Amount of assets to withdraw |
controller | address | Address that will control the request (must be msg.sender) |
owner | address | Address that owns the shares (must be msg.sender) |
Returns
| Name | Type | Description |
|---|---|---|
requestId | uint256 | ID of the request (always 0) |
cooldownRemaining
Returns the remaining cooldown time for a request
function cooldownRemaining(uint256 requestId, address owner) external view returns (uint48 cooldown);
Parameters
| Name | Type | Description |
|---|---|---|
requestId | uint256 | ID of the request (ignored) |
owner | address | Address that owns the shares (must be msg.sender) |
Returns
| Name | Type | Description |
|---|---|---|
cooldown | uint48 | Remaining cooldown time in seconds |
isClaimable
Returns true if a request is claimable
function isClaimable(uint256 requestId, address owner) external view returns (bool);
Parameters
| Name | Type | Description |
|---|---|---|
requestId | uint256 | ID of the request (ignored) |
owner | address | Address that owns the shares (must be msg.sender) |
Returns
| Name | Type | Description |
|---|---|---|
<none> | bool | true if the request is claimable, false otherwise |
supplyCap
Returns the current supply cap
function supplyCap() external view returns (uint256);
Returns
| Name | Type | Description |
|---|---|---|
<none> | uint256 | Maximum total supply allowed |
supplyCapRemaining
Returns the remaining capacity before hitting the supply cap
function supplyCapRemaining() external view returns (uint256);
Returns
| Name | Type | Description |
|---|---|---|
<none> | uint256 | Amount of tokens that can still be minted |
Events
UnlockingDelayUpdated
Emitted when the redeem (unlocking) cooldown is updated
event UnlockingDelayUpdated(uint48 oldUnlockingDelay, uint48 newUnlockingDelay);
Parameters
| Name | Type | Description |
|---|---|---|
oldUnlockingDelay | uint48 | Previous unlocking delay period in seconds |
newUnlockingDelay | uint48 | New unlocking delay period in seconds |
DenyListUpdated
Emitted when the deny list contract is updated
event DenyListUpdated(address indexed oldDenyList, address indexed newDenyList);
Parameters
| Name | Type | Description |
|---|---|---|
oldDenyList | address | Previous deny list contract address |
newDenyList | address | New deny list contract address |
SupplyCapUpdated
Emitted when the supply cap is updated
event SupplyCapUpdated(uint256 oldCap, uint256 newCap);
Parameters
| Name | Type | Description |
|---|---|---|
oldCap | uint256 | Previous supply cap |
newCap | uint256 | New supply cap |
Errors
NoClaimableRequest
Error thrown when trying to claim a non-existent or non-claimable request
error NoClaimableRequest();
NoPendingRequest
Error thrown when trying to cancel a non-existent request
error NoPendingRequest();
RequestNotClaimable
Error thrown when trying to claim before cooldown period passes
error RequestNotClaimable();
InvalidCooldown
Error thrown when setting invalid cooldown values
error InvalidCooldown();
Structs
Request
Request data structure used for both deposits and redeems
The meaning of fields changes based on which mapping stores the request
struct Request {
uint256 assets;
uint256 shares;
uint48 requestedAt;
}
Properties
| Name | Type | Description |
|---|---|---|
assets | uint256 | Pending assets to deposit (deposit request) OR locked-in assets to receive (redeem request) |
shares | uint256 | Locked-in shares to receive (deposit request) OR pending shares to redeem (redeem request) |
requestedAt | uint48 | Timestamp of last request (resets on incremental requests) |
IMinterV0
Inherits: EInvalidAddress, EInvalidAmount
Title: IMinterV0
Interface for the MinterV0 contract
Defines structs, enums, events, errors, and public functions for apxUSD minting
Functions
hashOrder
Returns the EIP-712 typed hash for an order
function hashOrder(Order calldata order) external view returns (bytes32);
Parameters
| Name | Type | Description |
|---|---|---|
order | Order | The mint order to hash |
Returns
| Name | Type | Description |
|---|---|---|
<none> | bytes32 | The EIP-712 typed hash |
validateOrder
Validates an order without executing it (reverts if invalid)
function validateOrder(Order calldata order, bytes calldata signature) external view;
Parameters
| Name | Type | Description |
|---|---|---|
order | Order | The mint order to validate |
signature | bytes | The beneficiary's signature over the order |
requestMint
Requests a mint by validating the order and scheduling with AccessManager
function requestMint(Order calldata order, bytes calldata signature) external returns (bytes32 operationId);
Parameters
| Name | Type | Description |
|---|---|---|
order | Order | The mint order |
signature | bytes | The beneficiary's signature over the order |
Returns
| Name | Type | Description |
|---|---|---|
operationId | bytes32 | The unique identifier for this scheduled operation |
executeMint
Executes a scheduled mint operation via AccessManager
function executeMint(bytes32 operationId) external;
Parameters
| Name | Type | Description |
|---|---|---|
operationId | bytes32 | The unique identifier of the scheduled operation |
cancelMint
Cancels a scheduled mint operation
function cancelMint(bytes32 operationId) external;
Parameters
| Name | Type | Description |
|---|---|---|
operationId | bytes32 | The unique identifier of the scheduled operation |
setMaxMintAmount
Updates the maximum mint amount
function setMaxMintAmount(uint208 newMaxMintAmount) external;
Parameters
| Name | Type | Description |
|---|---|---|
newMaxMintAmount | uint208 | New maximum amount for a single mint order |
setRateLimit
Updates the rate limit configuration
function setRateLimit(uint256 newAmount, uint48 newPeriod) external;
Parameters
| Name | Type | Description |
|---|---|---|
newAmount | uint256 | New maximum amount that can be minted within the rate limit period |
newPeriod | uint48 | New duration of the rate limit period in seconds |
cleanMintHistory
Manually cleans up to n expired mint records from the history queue
function cleanMintHistory(uint32 n) external returns (uint32 cleaned);
Parameters
| Name | Type | Description |
|---|---|---|
n | uint32 | Maximum number of records to attempt cleaning |
Returns
| Name | Type | Description |
|---|---|---|
cleaned | uint32 | Number of records actually removed |
nonce
Returns the current nonce for a beneficiary
function nonce(address beneficiary) external view returns (uint48);
Parameters
| Name | Type | Description |
|---|---|---|
beneficiary | address | Address to query nonce for |
Returns
| Name | Type | Description |
|---|---|---|
<none> | uint48 | Current nonce value |
pendingOrder
Returns the details of a pending order
function pendingOrder(bytes32 operationId) external view returns (Order memory);
Parameters
| Name | Type | Description |
|---|---|---|
operationId | bytes32 | The unique identifier of the scheduled operation |
Returns
| Name | Type | Description |
|---|---|---|
<none> | Order | order The pending order details |
mintStatus
Returns the status of a mint operation
function mintStatus(bytes32 operationId) external view returns (MintStatus);
Parameters
| Name | Type | Description |
|---|---|---|
operationId | bytes32 | The unique identifier of the operation |
Returns
| Name | Type | Description |
|---|---|---|
<none> | MintStatus | status The current status of the operation |
rateLimit
Returns the current rate limit configuration
function rateLimit() external view returns (uint256 amount, uint48 period);
Returns
| Name | Type | Description |
|---|---|---|
amount | uint256 | Maximum amount that can be minted within the rate limit period |
period | uint48 | Duration of the rate limit period in seconds |
maxMintAmount
Returns the current max mint amount
function maxMintAmount() external view returns (uint208);
Returns
| Name | Type | Description |
|---|---|---|
<none> | uint208 | Maximum amount that can be minted in a single order |
rateLimitMinted
Returns the total amount minted in the current rate limit period
function rateLimitMinted() external view returns (uint256);
Returns
| Name | Type | Description |
|---|---|---|
<none> | uint256 | Total amount minted in the current period |
rateLimitAvailable
Returns the amount available to mint without exceeding the rate limit
function rateLimitAvailable() external view returns (uint256);
Returns
| Name | Type | Description |
|---|---|---|
<none> | uint256 | Amount that can still be minted in the current period |
Events
MintRequested
Emitted when a mint is requested
event MintRequested(
bytes32 indexed operationId,
address indexed beneficiary,
uint208 amount,
uint48 nonce,
uint48 notBefore,
uint48 notAfter
);
MintExecuted
Emitted when a mint is executed
event MintExecuted(bytes32 indexed operationId, address indexed beneficiary);
MintCancelled
Emitted when a mint is cancelled
event MintCancelled(bytes32 indexed operationId, address indexed beneficiary, address indexed cancelledBy);
MaxMintAmountUpdated
Emitted when max mint amount is updated
event MaxMintAmountUpdated(uint256 oldMax, uint256 newMax);
RateLimitUpdated
Emitted when rate limit is updated
event RateLimitUpdated(uint256 oldAmount, uint48 oldPeriod, uint256 newAmount, uint48 newPeriod);
Errors
InvalidSignature
Error thrown when signature is invalid
TODO: Update to clarify usage (signer != beneficiary)
error InvalidSignature();
InvalidNonce
Error thrown when nonce is invalid
error InvalidNonce(uint48 expected, uint48 provided);
OrderInvalidTimeWindow
Error thrown when order time window is invalid (notAfter < notBefore)
error OrderInvalidTimeWindow();
OrderNotYetValid
Error thrown when current time is before notBefore
error OrderNotYetValid();
OrderExpired
Error thrown when current time is after notAfter
error OrderExpired();
MintAmountTooLarge
Error thrown when mint amount exceeds maximum
error MintAmountTooLarge(uint208 amount, uint208 maxAmount);
OrderNotFound
Error thrown when operation has no stored order
error OrderNotFound();
RateLimitExceeded
Error thrown when mint would exceed period rate limit
error RateLimitExceeded(uint208 requestedAmount, uint256 availableCapacity);
Structs
Order
Struct representing a mint order
Packed into 2 storage slots for gas efficiency
struct Order {
address beneficiary; // 160 bits - slot 0
uint48 notBefore; // 48 bits - slot 0
uint48 notAfter; // 48 bits - slot 0
// ============================================= slot boundary
uint48 nonce; // 48 bits - slot 1
uint208 amount; // 208 bits - slot 1
}
MintRecord
Struct to track mint timestamps and amounts for rate limiting
struct MintRecord {
uint48 timestamp;
uint208 amount; // Packed to fit in single slot with timestamp
}
Enums
MintStatus
Enum representing the status of a mint operation
enum MintStatus {
NotFound, // Order not in storage (never existed, or was executed/cancelled)
Scheduled, // Order pending, before notBefore time or AccessManager delay not passed
Ready, // Order pending and ready to execute (delay passed, within time window)
Expired // Order pending, after notAfter (expired)
}
IRedemptionPool
Inherits: IAccessManaged, EInvalidAddress, EInvalidAmount, EInsufficientBalance, ESlippageExceeded
Functions
redeem
Redeem assets for reserve assets at the current exchange rate
Requires ROLE_REDEEMER. Burns/transfers assets and sends reserve assets
function redeem(uint256 assetsAmount, address receiver, uint256 minReserveAssetOut)
external
returns (uint256 reserveAmount);
Parameters
| Name | Type | Description |
|---|---|---|
assetsAmount | uint256 | Amount of assets to redeem |
receiver | address | Address to receive the reserve assets |
minReserveAssetOut | uint256 | Minimum reserve assets to receive (slippage protection) |
Returns
| Name | Type | Description |
|---|---|---|
reserveAmount | uint256 | Amount of reserve assets received |
previewRedeem
Preview how much reserve assets would be received for a given assets amount
function previewRedeem(uint256 assetsAmount) external view returns (uint256 reserveAmount);
Parameters
| Name | Type | Description |
|---|---|---|
assetsAmount | uint256 | Amount of assets to preview |
Returns
| Name | Type | Description |
|---|---|---|
reserveAmount | uint256 | Amount of reserve assets that would be received |
deposit
Deposit reserve assets into the contract to fund redemptions
function deposit(uint256 reserveAmount) external;
Parameters
| Name | Type | Description |
|---|---|---|
reserveAmount | uint256 | Amount of reserve assets to deposit |
withdraw
Withdraw excess reserve assets from the contract
Restricted to admin role
function withdraw(uint256 reserveAmount, address receiver) external;
Parameters
| Name | Type | Description |
|---|---|---|
reserveAmount | uint256 | Amount of reserve assets to withdraw |
receiver | address | Address to receive the reserve assets |
withdrawTokens
Withdraw excess assets from the contract
Restricted to admin role
This function is used to support withdrawing tokens that are erroneously deposited to the redemption pool.
function withdrawTokens(address withdrawAsset, uint256 amount, address receiver) external;
Parameters
| Name | Type | Description |
|---|---|---|
withdrawAsset | address | Address of the asset to withdraw |
amount | uint256 | Amount of the asset to withdraw |
receiver | address | Address to receive the asset |
setExchangeRate
Update the exchange rate (assets to reserve assets)
Restricted to admin role
function setExchangeRate(uint256 newRate) external;
Parameters
| Name | Type | Description |
|---|---|---|
newRate | uint256 | New exchange rate in assets per reserve asset (1e18 = 1 asset per reserve asset) |
exchangeRate
Get the current exchange rate
function exchangeRate() external view returns (uint256);
Returns
| Name | Type | Description |
|---|---|---|
<none> | uint256 | Exchange rate in assets per reserve asset (1e18 = 1 asset per reserve asset) |
asset
Get the asset token address
function asset() external view returns (ERC20Burnable);
Returns
| Name | Type | Description |
|---|---|---|
<none> | ERC20Burnable | Address of the asset token |
reserveAsset
Get the reserve asset token address
function reserveAsset() external view returns (IERC20);
Returns
| Name | Type | Description |
|---|---|---|
<none> | IERC20 | Address of the reserve asset token |
reserveBalance
Get the current reserve asset balance
function reserveBalance() external view returns (uint256);
Returns
| Name | Type | Description |
|---|---|---|
<none> | uint256 | Reserve asset balance available for redemptions |
Events
Redeemed
Emitted when assets are redeemed for reserve assets
event Redeemed(address indexed redeemer, uint256 assetsAmount, uint256 reserveAmount);
Parameters
| Name | Type | Description |
|---|---|---|
redeemer | address | Address that performed the redemption |
assetsAmount | uint256 | Amount of assets burned/transferred |
reserveAmount | uint256 | Amount of reserve assets received |
ExchangeRateUpdated
Emitted when the exchange rate is updated
event ExchangeRateUpdated(uint256 oldRate, uint256 newRate);
Parameters
| Name | Type | Description |
|---|---|---|
oldRate | uint256 | Previous exchange rate |
newRate | uint256 | New exchange rate |
Withdraw
Emitted when tokens are withdrawn via withdrawTokens
event Withdraw(address indexed caller, address indexed withdrawAsset, uint256 amount, address indexed receiver);
Parameters
| Name | Type | Description |
|---|---|---|
caller | address | Address that initiated the withdrawal (admin) |
withdrawAsset | address | Address of the token withdrawn |
amount | uint256 | Amount withdrawn |
receiver | address | Address that received the tokens |
ReservesDeposited
Emitted when reserve assets are deposited into the pool
event ReservesDeposited(address indexed depositor, uint256 amount);
Parameters
| Name | Type | Description |
|---|---|---|
depositor | address | Address that deposited the reserve assets |
amount | uint256 | Amount of reserve assets deposited |
IUnlockToken
Inherits: ICommitToken
Title: IUnlockToken
Interface for UnlockToken contract that allows a vault to act as an operator
Functions
vault
Returns the vault address that can act as an operator
function vault() external view returns (address);
Returns
| Name | Type | Description |
|---|---|---|
<none> | address | The vault address (immutable, set at construction) |
IVesting
Inherits: EInvalidAddress, EInvalidAmount
Title: IVesting
Interface for the Vesting contract that handles yield distribution. Different implementations may have different vesting periods and yield distribution mechanisms.
Defines functions, events, and errors for yield vesting functionality
Functions
asset
Returns the asset token address
function asset() external view returns (IERC20);
Returns
| Name | Type | Description |
|---|---|---|
<none> | IERC20 | Address of the asset token |
vestingPeriod
Returns the current vesting period in seconds
function vestingPeriod() external view returns (uint256);
Returns
| Name | Type | Description |
|---|---|---|
<none> | uint256 | Vesting period in seconds |
vestingPeriodStart
Returns the start of the current vesting period
function vestingPeriodStart() external view returns (uint256);
Returns
| Name | Type | Description |
|---|---|---|
<none> | uint256 | Start of the current vesting period |
vestingPeriodRemaining
Returns the remaining time in the current vesting period
function vestingPeriodRemaining() external view returns (uint256);
Returns
| Name | Type | Description |
|---|---|---|
<none> | uint256 | Remaining time in the current vesting period |
vestingPeriodEnd
Returns the end of the current vesting period
function vestingPeriodEnd() external view returns (uint256);
Returns
| Name | Type | Description |
|---|---|---|
<none> | uint256 | End of the current vesting period |
vestedAmount
Returns the amount of yield that has vested and is available, including fully vested and newly vested yield.
function vestedAmount() external view returns (uint256);
Returns
| Name | Type | Description |
|---|---|---|
<none> | uint256 | Amount of vested yield including fully vested and newly vested yield |
newlyVestedAmount
Returns the amount of yield that has been newly vested since the last transfer
function newlyVestedAmount() external view returns (uint256);
Returns
| Name | Type | Description |
|---|---|---|
<none> | uint256 | Amount of newly vested yield |
unvestedAmount
Returns the amount of yield that is still vesting
function unvestedAmount() external view returns (uint256);
Returns
| Name | Type | Description |
|---|---|---|
<none> | uint256 | Amount of unvested yield |
setBeneficiary
Sets the beneficiary address. This is used when initializing the vesting contract, to set the beneficiary address and when migrating to a new vesting contract.
Only callable through AccessManager with ADMIN_ROLE
function setBeneficiary(address newBeneficiary) external;
Parameters
| Name | Type | Description |
|---|---|---|
newBeneficiary | address | New beneficiary contract address |
setVestingPeriod
Sets the vesting period
Only callable through AccessManager with ADMIN_ROLE
function setVestingPeriod(uint256 newPeriod) external;
Parameters
| Name | Type | Description |
|---|---|---|
newPeriod | uint256 | New vesting period in seconds |
depositYield
Deposits yield into the vesting contract
Resets the vesting period, adding vested yield to the fullyVestedAmount and the new deposit amount to the vestingAmount.
function depositYield(uint256 amount) external;
Parameters
| Name | Type | Description |
|---|---|---|
amount | uint256 | Amount of yield to deposit |
pullVestedYield
Transfers all vested yield to the vault
Only callable by vault contract. No-op if no vested yield available.
function pullVestedYield() external;
Events
YieldDeposited
Emitted when yield is deposited into the vesting contract
event YieldDeposited(address indexed depositor, uint256 amount);
Parameters
| Name | Type | Description |
|---|---|---|
depositor | address | Address that deposited the yield |
amount | uint256 | Amount of yield deposited |
VestedYieldTransferred
Emitted when vested yield is transferred out
event VestedYieldTransferred(address indexed beneficiary, uint256 amount);
Parameters
| Name | Type | Description |
|---|---|---|
beneficiary | address | Address receiving the vested yield (beneficiary) |
amount | uint256 | Amount of vested yield transferred |
VestingPeriodUpdated
Emitted when the vesting period is updated
event VestingPeriodUpdated(uint256 oldPeriod, uint256 newPeriod);
Parameters
| Name | Type | Description |
|---|---|---|
oldPeriod | uint256 | Previous vesting period in seconds |
newPeriod | uint256 | New vesting period in seconds |
BeneficiaryUpdated
Emitted when the vault contract address is updated
event BeneficiaryUpdated(address oldBeneficiary, address newBeneficiary);
Parameters
| Name | Type | Description |
|---|---|---|
oldBeneficiary | address | Previous beneficiary contract address |
newBeneficiary | address | New beneficiary contract address |
Errors
UnauthorizedTransfer
Error thrown when an unauthorized address attempts to transfer vested yield
error UnauthorizedTransfer();
IYieldDistributor
Inherits: EInvalidAddress, EInvalidAmount, EInsufficientBalance
Title: IYieldDistributor
Interface for the YieldDistributor contract that receives yield from MinterV0 and deposits it to Vesting
Defines functions, events, and errors for yield distribution functionality
Functions
asset
Returns the asset token address (apxUSD)
function asset() external view returns (IERC20);
Returns
| Name | Type | Description |
|---|---|---|
<none> | IERC20 | Address of the asset token |
vesting
Returns the vesting contract address
function vesting() external view returns (IVesting);
Returns
| Name | Type | Description |
|---|---|---|
<none> | IVesting | Address of the vesting contract |
availableBalance
Returns the available balance of apxUSD tokens
function availableBalance() external view returns (uint256);
Returns
| Name | Type | Description |
|---|---|---|
<none> | uint256 | Amount of apxUSD tokens available for deposit |
setVesting
Sets the vesting contract address
Only callable through AccessManager with ADMIN_ROLE
function setVesting(address newVesting) external;
Parameters
| Name | Type | Description |
|---|---|---|
newVesting | address | New vesting contract address |
setSigningDelegate
Sets the signature delegate
Only callable through AccessManager with ADMIN_ROLE
function setSigningDelegate(address newSigningDelegate) external;
Parameters
| Name | Type | Description |
|---|---|---|
newSigningDelegate | address | New signature delegate address |
depositYield
Deposits yield to the vesting contract
Only callable through AccessManager with ROLE_YIELD_OPERATOR
function depositYield(uint256 amount) external;
Parameters
| Name | Type | Description |
|---|---|---|
amount | uint256 | Amount of yield to deposit |
withdraw
Withdraws yield from the vesting contract
Only callable through AccessManager with ADMIN_ROLE
function withdraw(uint256 amount, address receiver) external;
Parameters
| Name | Type | Description |
|---|---|---|
amount | uint256 | Amount of yield to withdraw |
receiver | address | Address to receive the yield |
withdrawTokens
Withdraws tokens from the YieldDistributor
Only callable through AccessManager with ADMIN_ROLE
This function is used to support withdrawing tokens that are erroneously sent to the YieldDistributor (e.g. not apxUSD, any other ERC20).
function withdrawTokens(address withdrawAsset, uint256 amount, address receiver) external;
Parameters
| Name | Type | Description |
|---|---|---|
withdrawAsset | address | Address of the asset to withdraw |
amount | uint256 | Amount of the asset to withdraw |
receiver | address | Address to receive the asset |
Events
VestingContractUpdated
Emitted when the vesting contract address is updated
event VestingContractUpdated(address indexed oldVesting, address indexed newVesting);
Parameters
| Name | Type | Description |
|---|---|---|
oldVesting | address | Previous vesting contract address |
newVesting | address | New vesting contract address |
SigningDelegateUpdated
Emitted when the signature delegate is updated
event SigningDelegateUpdated(address indexed oldSigningDelegate, address indexed newSigningDelegate);
Parameters
| Name | Type | Description |
|---|---|---|
oldSigningDelegate | address | Previous signature delegate address |
newSigningDelegate | address | New signature delegate address |
YieldDeposited
Emitted when yield is deposited to the vesting contract
event YieldDeposited(address indexed operator, uint256 amount);
Parameters
| Name | Type | Description |
|---|---|---|
operator | address | Address of the operator that triggered the yield to be deposited |
amount | uint256 | Amount of yield deposited |
Withdraw
Emitted when tokens are withdrawn via withdrawTokens
event Withdraw(address indexed caller, address indexed withdrawAsset, uint256 amount, address indexed receiver);
Parameters
| Name | Type | Description |
|---|---|---|
caller | address | Address that initiated the withdrawal (admin) |
withdrawAsset | address | Address of the token withdrawn |
amount | uint256 | Amount withdrawn |
receiver | address | Address that received the tokens |
Errors
VestingNotSet
Error thrown when vesting contract is not set
error VestingNotSet();
Contents
ApxUSDRateOracle
Inherits: Initializable, AccessManagedUpgradeable, UUPSUpgradeable, EInvalidAmount
Title: ApxUSDRateOracle
Provides the exchange rate of apxUSD relative to USDC for Curve Stableswap-NG pools.
The rate represents how many USDC 1 apxUSD is worth based on the off-chain collateral backing apxUSD, expressed as a uint256 with 1e18 precision.
- 1e18 = 1 apxUSD is worth 1 USDC
- 1.02e18 = 1 apxUSD is worth 1.02 USDC
Called by the Curve pool via staticcall to
rate().
State Variables
STORAGE_LOCATION
bytes32 private constant STORAGE_LOCATION = 0x27bd078109e9748e45a8094381d0fb92b7b8cc1084b35874a4d9e8826ec4f100
Functions
_getStorage
function _getStorage() private pure returns (ApxUSDRateOracleStorage storage $);
constructor
Note: oz-upgrades-unsafe-allow: constructor
constructor() ;
initialize
Initializes the oracle with a default rate of 1e18 (1:1 peg).
function initialize(address initialAuthority) external initializer;
Parameters
| Name | Type | Description |
|---|---|---|
initialAuthority | address | The address of the authority that can set the rate. |
rate
Returns the current rate of apxUSD relative to USDC.
function rate() external view returns (uint256);
Returns
| Name | Type | Description |
|---|---|---|
<none> | uint256 | The current rate in 1e18 precision. |
setRate
Sets the rate of apxUSD relative to USDC.
function setRate(uint256 newRate) external restricted;
Parameters
| Name | Type | Description |
|---|---|---|
newRate | uint256 | The new rate in 1e18 precision (must be > 0). |
_authorizeUpgrade
function _authorizeUpgrade(address newImplementation) internal override restricted;
Events
RateUpdated
event RateUpdated(uint256 oldRate, uint256 newRate);
Structs
ApxUSDRateOracleStorage
Note: storage-location: erc7201:apyx.storage.ApxUSDRateOracle
struct ApxUSDRateOracleStorage {
uint256 rate;
}
ApyUSDRateOracle
Inherits: Initializable, AccessManagedUpgradeable, UUPSUpgradeable, EInvalidAmount, EInvalidAddress
Title: ApyUSDRateOracle
Provides the exchange rate of apyUSD for a Curve Stableswap-NG pool.
Reads convertToAssets(1e18) from the apyUSD ERC-4626 vault and multiplies
by a configurable adjustment. Called by the Curve pool via staticcall to rate().
The full call chain is read-only; standard ERC-4626 vaults satisfy this requirement.
State Variables
MIN_ADJUSTMENT
Minimum allowed adjustment (90% — discounts apyUSD by up to 10%)
uint256 public constant MIN_ADJUSTMENT = 0.9e18
MAX_ADJUSTMENT
Maximum allowed adjustment (110% — premiums apyUSD by up to 10%)
uint256 public constant MAX_ADJUSTMENT = 1.1e18
STORAGE_LOCATION
bytes32 private constant STORAGE_LOCATION = 0x7c3fd745b6b17d3e08ed287c3401ed4dbb5b9270e485a2fb2e22ca2d91e6e000
Functions
_getStorage
function _getStorage() private pure returns (ApyUSDRateOracleStorage storage $);
constructor
Note: oz-upgrades-unsafe-allow: constructor
constructor() ;
initialize
Initializes the oracle with neutral adjustment (1e18) and the apyUSD vault address.
function initialize(address initialAuthority, address vault_) external initializer;
Parameters
| Name | Type | Description |
|---|---|---|
initialAuthority | address | The AccessManager address. |
vault_ | address | The apyUSD ERC-4626 vault address. |
rate
Returns the current rate fed to the Curve pool.
function rate() external view returns (uint256);
Returns
| Name | Type | Description |
|---|---|---|
<none> | uint256 | The apyUSD redemption rate multiplied by adjustment, in 1e18 precision. |
adjustment
Returns the current adjustment value.
function adjustment() external view returns (uint256);
Returns
| Name | Type | Description |
|---|---|---|
<none> | uint256 | The current adjustment in 1e18 precision (1e18 = neutral). |
vault
Returns the apyUSD ERC-4626 vault address this oracle reads from.
function vault() external view returns (address);
Returns
| Name | Type | Description |
|---|---|---|
<none> | address | The apyUSD vault address. |
setAdjustment
Sets the adjustment value. Must be within [MIN_ADJUSTMENT, MAX_ADJUSTMENT].
function setAdjustment(uint256 newAdjustment) external restricted;
Parameters
| Name | Type | Description |
|---|---|---|
newAdjustment | uint256 | New adjustment value in 1e18 precision. |
_authorizeUpgrade
function _authorizeUpgrade(address newImplementation) internal override restricted;
Events
AdjustmentUpdated
event AdjustmentUpdated(uint256 oldAdjustment, uint256 newAdjustment);
Structs
ApyUSDRateOracleStorage
Note: storage-location: erc7201:apyx.storage.ApyUSDRateOracle
struct ApyUSDRateOracleStorage {
uint256 adjustment;
address vault;
}
Contents
OrderDelegate
Inherits: ERC1271Delegated, AccessManaged, Pausable, ReentrancyGuardTransient, EInvalidAmount, EInsufficientBalance
Title: OrderDelegate
Contract skeleton for delegated order signing and execution
State Variables
beneficiary
Beneficiary address that receives minted/received assets
address public immutable beneficiary
asset
Asset token (e.g. apxUSD)
IERC20 public immutable asset
Functions
constructor
Initializes the order delegate
constructor(address _authority, address _beneficiary, address _signingDelegate, address _asset)
AccessManaged(_authority)
ERC1271Delegated(_signingDelegate);
Parameters
| Name | Type | Description |
|---|---|---|
_authority | address | Address of the AccessManager contract |
_beneficiary | address | Beneficiary that receives assets |
_signingDelegate | address | Address that may sign on behalf of this contract |
_asset | address | Asset token |
isValidSignature
ERC-1271: when paused, reverts so no new mints to this beneficiary
function isValidSignature(bytes32 hash, bytes calldata signature)
public
view
override
whenNotPaused
returns (bytes4 magicValue);
pause
Pauses the contract (isValidSignature will revert when paused). No unpause.
function pause() external restricted;
transfer
Transfers the configured asset to the beneficiary (convenience for primary mint token)
function transfer(uint256 amount) external restricted;
Parameters
| Name | Type | Description |
|---|---|---|
amount | uint256 | Amount to transfer |
transferToken
Transfers an ERC20 from this contract to the beneficiary
function transferToken(address token, uint256 amount) public restricted nonReentrant;
Parameters
| Name | Type | Description |
|---|---|---|
token | address | Token address |
amount | uint256 | Amount to transfer |
Contents
ApyUSDRateView
Inherits: EInvalidAddress
Title: ApyUSDRateView
View contract that computes the current APY for an ApyUSD vault from its total assets and the vesting contract's yield rate (unvested amount per vesting period remaining).
Vault is set at deployment. Yield per second = unvestedAmount() / vestingPeriodRemaining(). Returns 0 when totalAssets is zero, vesting is not set, or vesting period remaining is zero. Values returned by apr() and apy() are approximations and may include rounding errors due to integer division and fixed-point math.
State Variables
SECONDS_PER_YEAR
Seconds per year (365.25 days) for annualizing the yield rate
uint256 public constant SECONDS_PER_YEAR = 31_557_600
vault
The ApyUSD vault address this view reads from
address public immutable vault
Functions
constructor
Sets the vault address at deployment
constructor(address vault_) ;
Parameters
| Name | Type | Description |
|---|---|---|
vault_ | address | Address of the ApyUSD vault (must not be zero) |
annualizedYield
Returns the annualized yield (unvested per second × SECONDS_PER_YEAR)
function annualizedYield() public view returns (uint256 annualYield);
Returns
| Name | Type | Description |
|---|---|---|
annualYield | uint256 | Annualized yield in asset units, or 0 if no vesting or zero period remaining |
apr
Returns the current APR as an 18-decimal fraction (e.g. 0.05e18 = 5%)
Approximate; rounding may occur in annualizedYield and in the division by totalAssets.
function apr() public view returns (uint256 annualRate);
Returns
| Name | Type | Description |
|---|---|---|
annualRate | uint256 | APR or 0 when totalAssets is zero, vesting is not set, or period remaining is zero |
apy
Returns the current APY as an 18-decimal fraction (e.g. 0.05e18 = 5%)
Assumes the annual rate is compounded monthly based on monthly dividend yields. Approximate; rounding may occur in apr(), in base computation, and in rpow.
function apy() public view returns (uint256 annualYield);
Returns
| Name | Type | Description |
|---|---|---|
annualYield | uint256 | APY or 0 when annualRate is zero |
AddressList
Inherits: AccessManaged, IAddressList, EInvalidAddress
Title: AddressList
Central address list management for the Apyx protocol
Provides a single source of truth for blocked/allowed addresses across all Apyx contracts Features:
- Centralized address management
- Access controlled via AccessManager
- Enumerable for off-chain iteration
- Gas-efficient set operations
State Variables
_addresses
Set of addresses in the list
EnumerableSet.AddressSet private _addresses
Functions
constructor
Initializes the AddressList contract
constructor(address initialAuthority) AccessManaged(initialAuthority);
Parameters
| Name | Type | Description |
|---|---|---|
initialAuthority | address | Address of the AccessManager contract |
add
Adds an address to the list
Only callable through AccessManager with appropriate role
function add(address user) external override restricted;
Parameters
| Name | Type | Description |
|---|---|---|
user | address | Address to add |
remove
Removes an address from the list
Only callable through AccessManager with appropriate role
function remove(address user) external override restricted;
Parameters
| Name | Type | Description |
|---|---|---|
user | address | Address to remove |
contains
Checks if an address is in the list
function contains(address user) external view override returns (bool);
Parameters
| Name | Type | Description |
|---|---|---|
user | address | Address to check |
Returns
| Name | Type | Description |
|---|---|---|
<none> | bool | True if address is in the list, false otherwise |
length
Returns the number of addresses in the list
function length() external view override returns (uint256);
Returns
| Name | Type | Description |
|---|---|---|
<none> | uint256 | Number of addresses |
at
Returns the address at the given index
function at(uint256 index) external view override returns (address);
Parameters
| Name | Type | Description |
|---|---|---|
index | uint256 | Index of the address to retrieve |
Returns
| Name | Type | Description |
|---|---|---|
<none> | address | Address at the given index |
ApxUSD
Inherits: Initializable, ERC20Upgradeable, ERC20PermitUpgradeable, ERC20PausableUpgradeable, ERC20DenyListUpgradable, ERC20BurnableUpgradeable, AccessManagedUpgradeable, UUPSUpgradeable
Title: ApxUSD
A stablecoin backed by off-chain preferred shares with dividend yields
Implements ERC-20 with Permit (EIP-2612), pausability, deny listing, and role-based access control Features:
- Supply cap to limit total issuance
- MINT_STRAT for authorized minting contracts
- Pausable for emergency situations
- DenyList addresses for compliance
- UUPS upgradeable pattern
State Variables
APXUSD_STORAGE_LOC
bytes32 private constant APXUSD_STORAGE_LOC = 0xd4bd5aaf4064e82ca5c0ebf6f76b7f421377722e7c3f989b53116d58938a1600
Functions
_getApxUSDStorage
function _getApxUSDStorage() private pure returns (ApxUSDStorage storage $);
constructor
Note: oz-upgrades-unsafe-allow: constructor
constructor() ;
initialize
Initializes the ApxUSD contract
function initialize(
string memory name,
string memory symbol,
address initialAuthority,
address initialDenyList,
uint256 initialSupplyCap
) public initializer;
Parameters
| Name | Type | Description |
|---|---|---|
name | string | |
symbol | string | |
initialAuthority | address | Address of the AccessManager contract |
initialDenyList | address | |
initialSupplyCap | uint256 | Maximum total supply (e.g., 1_000_000e18 for $1M) |
_authorizeUpgrade
Authorizes contract upgrades
Only callable through AccessManager
function _authorizeUpgrade(address newImplementation) internal override restricted;
mint
Mints new apxUSD tokens
Only callable through AccessManager with MINT_STRAT_ROLE
The nonce is not enforced in ApxUSD and is only included to ensure uniqueness when scheduling operations with AccessManager. The nonce MUST be enforced by a Minter contract (ie MinterV0).
function mint(address to, uint256 amount, uint256 nonce) external restricted;
Parameters
| Name | Type | Description |
|---|---|---|
to | address | Address to receive the minted tokens |
amount | uint256 | Amount of tokens to mint (in wei, 18 decimals) |
nonce | uint256 | Nonce for the mint |
_update
Hook that is called before any token transfer
Enforces pause and freeze functionality
function _update(address from, address to, uint256 value)
internal
override(ERC20Upgradeable, ERC20PausableUpgradeable, ERC20DenyListUpgradable);
setSupplyCap
Updates the supply cap
Only callable through AccessManager with ADMIN_ROLE
function setSupplyCap(uint256 newSupplyCap) external restricted;
Parameters
| Name | Type | Description |
|---|---|---|
newSupplyCap | uint256 | New maximum total supply |
supplyCap
Returns the current supply cap
function supplyCap() external view returns (uint256);
Returns
| Name | Type | Description |
|---|---|---|
<none> | uint256 | Maximum total supply allowed |
supplyCapRemaining
Returns the remaining capacity before hitting the supply cap
function supplyCapRemaining() external view returns (uint256);
Returns
| Name | Type | Description |
|---|---|---|
<none> | uint256 | Amount of tokens that can still be minted |
pause
Pauses all token transfers
Only callable through AccessManager with ADMIN_ROLE
function pause() external restricted;
unpause
Unpauses all token transfers
Only callable through AccessManager with ADMIN_ROLE
function unpause() external restricted;
setDenyList
function setDenyList(IAddressList newDenyList) external restricted;
Events
SupplyCapUpdated
Emitted when the supply cap is updated
event SupplyCapUpdated(uint256 oldCap, uint256 newCap);
Errors
SupplyCapExceeded
Error thrown when minting would exceed the supply cap
error SupplyCapExceeded(uint256 requestedAmount, uint256 availableCapacity);
InvalidSupplyCap
Error thrown when setting an invalid supply cap
error InvalidSupplyCap();
Structs
ApxUSDStorage
Note: storage-location: erc7201:apyx.storage.ApxUSD
struct ApxUSDStorage {
/// @notice Maximum total supply allowed (in wei, 18 decimals)
uint256 supplyCap;
}
ApyUSD
Inherits: Initializable, ERC20PermitUpgradeable, ERC20PausableUpgradeable, ERC20DenyListUpgradable, AccessManagedUpgradeable, UUPSUpgradeable, ERC4626Upgradeable, IApyUSD, EInvalidCaller
Title: ApyUSD
ERC4626 synchronous tokenized vault for staking ApxUSD
Deposits and withdrawals are synchronous. Withdrawals delegate unlocking delay to UnlockToken. Features:
- Instant deposits/mints with deny list checking via AddressList
- Instant redeems/withdrawals that deposit assets to UnlockToken and start redeem requests
- UnlockToken handles the cooldown period and async claim flow
- ERC4626 compatibility
- Pausable and freezeable for compliance
- UUPS upgradeable pattern
State Variables
FEE_PRECISION
Fee precision constant (100% = 1e18)
uint256 private constant FEE_PRECISION = 1e18
MAX_FEE
Maximum fee allowed (1%)
uint256 private constant MAX_FEE = 0.01e18
APYUSD_STORAGE_LOC
bytes32 private constant APYUSD_STORAGE_LOC = 0x1ff8d3deae3efb825bbaa861079c5ce537ca15be7f99d50a5b2800b88987f100
Functions
_getApyUSDStorage
function _getApyUSDStorage() private pure returns (ApyUSDStorage storage $);
constructor
Note: oz-upgrades-unsafe-allow: constructor
constructor() ;
initialize
Initializes the ApyUSD vault
UnlockToken must be set after deployment using setUnlockToken()
function initialize(
string memory name,
string memory symbol,
address initialAuthority,
address asset,
address initialDenyList
) public initializer;
Parameters
| Name | Type | Description |
|---|---|---|
name | string | |
symbol | string | |
initialAuthority | address | Address of the AccessManager contract |
asset | address | Address of the underlying asset (ApxUSD) |
initialDenyList | address | Address of the AddressList contract for deny list checking |
_authorizeUpgrade
Authorizes contract upgrades
Only callable through AccessManager with ADMIN role
function _authorizeUpgrade(address newImplementation) internal override restricted;
_update
Hook that is called before any token transfer
Enforces pause, freeze, and deny list functionality
function _update(address from, address to, uint256 value)
internal
override(ERC20Upgradeable, ERC20PausableUpgradeable, ERC20DenyListUpgradable);
decimals
Returns the number of decimals used for the token
Overrides both ERC20 and ERC4626 decimals
function decimals() public view override(ERC20Upgradeable, ERC4626Upgradeable) returns (uint8);
_decimalsOffset
Returns the decimals offset for inflation attack protection
Can be overridden to add virtual shares/assets
function _decimalsOffset() internal pure override returns (uint8);
totalAssets
Returns the total amount of assets managed by the vault
Overrides ERC4626 to include vested yield from vesting contract
function totalAssets() public view override returns (uint256);
Returns
| Name | Type | Description |
|---|---|---|
<none> | uint256 | Total assets including vault balance and vested yield |
previewWithdraw
Preview adding an exit fee on withdrawal
Overrides ERC4626 to account for unlocking fees
function previewWithdraw(uint256 assets) public view override returns (uint256);
Parameters
| Name | Type | Description |
|---|---|---|
assets | uint256 | Amount of assets to withdraw (what user receives after fees) |
Returns
| Name | Type | Description |
|---|---|---|
<none> | uint256 | Amount of shares needed to withdraw the requested assets |
previewRedeem
Preview taking an exit fee on redeem
Overrides ERC4626 to account for unlocking fees
function previewRedeem(uint256 shares) public view override returns (uint256);
Parameters
| Name | Type | Description |
|---|---|---|
shares | uint256 | Amount of shares to redeem |
Returns
| Name | Type | Description |
|---|---|---|
<none> | uint256 | Amount of assets user will receive after fees are deducted |
_deposit
Internal deposit/mint function with deny list checking
Overrides ERC4626 internal function to add deny list checks
function _deposit(address caller, address receiver, uint256 assets, uint256 shares)
internal
override
checkNotDenied(caller)
checkNotDenied(receiver);
Parameters
| Name | Type | Description |
|---|---|---|
caller | address | Address initiating the deposit |
receiver | address | Address to receive the shares |
assets | uint256 | Amount of assets to deposit |
shares | uint256 | Amount of shares to mint |
_withdraw
Internal withdraw function that deposits assets to UnlockToken and starts redeem request
Overrides ERC4626 to delegate unlocking delay to UnlockToken
Fees are deducted from user shares but only transferred to feeWallet if it is set. When feeWallet is address(0) or address(this), fees remain in the vault and accrue to depositors.
function _withdraw(address caller, address receiver, address owner, uint256 assets, uint256 shares)
internal
override
checkNotDenied(caller)
checkNotDenied(receiver)
checkNotDenied(owner);
Parameters
| Name | Type | Description |
|---|---|---|
caller | address | Address initiating the withdrawal |
receiver | address | Address to receive the UnlockToken shares |
owner | address | Address that owns the shares |
assets | uint256 | Amount of assets to withdraw |
shares | uint256 | Amount of shares to burn |
setDenyList
Sets the deny list contract
Only callable through AccessManager with ADMIN_ROLE
function setDenyList(IAddressList newDenyList) external restricted;
Parameters
| Name | Type | Description |
|---|---|---|
newDenyList | IAddressList | Address of the new AddressList contract |
setUnlockToken
Sets the UnlockToken contract
Only callable through AccessManager with ADMIN_ROLE
No fund migration is performed - outstanding requests remain on old UnlockToken
function setUnlockToken(IUnlockToken newUnlockToken) external restricted;
Parameters
| Name | Type | Description |
|---|---|---|
newUnlockToken | IUnlockToken | The new UnlockToken contract |
unlockToken
Returns the current UnlockToken contract address
function unlockToken() external view returns (address);
Returns
| Name | Type | Description |
|---|---|---|
<none> | address | Address of the UnlockToken contract |
setVesting
Sets the Vesting contract
Only callable through AccessManager with ADMIN_ROLE
Setting to address(0) removes the vesting contract
function setVesting(IVesting newVesting) external restricted;
Parameters
| Name | Type | Description |
|---|---|---|
newVesting | IVesting | The new Vesting contract (can be address(0) to remove) |
vesting
Returns the current Vesting contract address
function vesting() external view returns (address);
Returns
| Name | Type | Description |
|---|---|---|
<none> | address | Address of the Vesting contract |
unlockingFee
Returns the current unlocking fee
function unlockingFee() public view returns (uint256);
Returns
| Name | Type | Description |
|---|---|---|
<none> | uint256 | Fee as a percentage with 18 decimals (e.g., 0.01e18 = 1%, 1e18 = 100%) |
setUnlockingFee
Sets the unlocking fee
Only callable through AccessManager with ADMIN_ROLE
function setUnlockingFee(uint256 fee) external restricted;
Parameters
| Name | Type | Description |
|---|---|---|
fee | uint256 | Fee as a percentage with 18 decimals (e.g., 0.01e18 = 1%, 1e18 = 100%) |
feeWallet
Returns the current fee wallet address
function feeWallet() public view returns (address);
Returns
| Name | Type | Description |
|---|---|---|
<none> | address | Address of the fee wallet |
setFeeWallet
Sets the fee wallet address
Only callable through AccessManager with ADMIN_ROLE
When feeWallet is address(0) or address(this), fees remain in the vault and accrue to depositors
function setFeeWallet(address wallet) external restricted;
Parameters
| Name | Type | Description |
|---|---|---|
wallet | address | Address to receive fees |
_feeOnRaw
Calculates the fees that should be added to an amount assets that does not already include fees
Used in previewWithdraw and _withdraw operations
function _feeOnRaw(uint256 assets, uint256 feePercentage) private pure returns (uint256);
Parameters
| Name | Type | Description |
|---|---|---|
assets | uint256 | The asset amount before fees |
feePercentage | uint256 | Fee as a percentage with 18 decimals (e.g., 0.01e18 = 1%, 1e18 = 100%) |
Returns
| Name | Type | Description |
|---|---|---|
<none> | uint256 | Fee amount to add |
_feeOnTotal
Calculates the fee part of an amount assets that already includes fees
Used in previewRedeem operations
function _feeOnTotal(uint256 assets, uint256 feePercentage) private pure returns (uint256);
Parameters
| Name | Type | Description |
|---|---|---|
assets | uint256 | The total asset amount including fees |
feePercentage | uint256 | Fee as a percentage with 18 decimals (e.g., 0.01e18 = 1%, 1e18 = 100%) |
Returns
| Name | Type | Description |
|---|---|---|
<none> | uint256 | Fee amount that is part of the total |
depositForMinShares
Deposits exact assets for shares or reverts if less than min shares will be minted
Provides slippage protection for deposits
function depositForMinShares(uint256 assets, uint256 minShares, address receiver)
external
returns (uint256 shares);
Parameters
| Name | Type | Description |
|---|---|---|
assets | uint256 | Amount of assets to deposit |
minShares | uint256 | Minimum amount of shares expected |
receiver | address | Address to receive the shares |
Returns
| Name | Type | Description |
|---|---|---|
shares | uint256 | Amount of shares minted |
mintForMaxAssets
Mint exact shares for assets or reverts if more than max assets will be deposited
Provides slippage protection for mints
function mintForMaxAssets(uint256 shares, uint256 maxAssets, address receiver) external returns (uint256 assets);
Parameters
| Name | Type | Description |
|---|---|---|
shares | uint256 | Amount of shares to mint |
maxAssets | uint256 | Maximum amount of assets willing to deposit |
receiver | address | Address to receive the shares |
Returns
| Name | Type | Description |
|---|---|---|
assets | uint256 | Amount of assets deposited |
withdrawForMaxShares
Withdraws exact assets for shares or reverts if more than max shares will be burned
Provides slippage protection for withdrawals
function withdrawForMaxShares(uint256 assets, uint256 maxShares, address receiver)
external
returns (uint256 shares);
Parameters
| Name | Type | Description |
|---|---|---|
assets | uint256 | Amount of assets to withdraw |
maxShares | uint256 | Maximum amount of shares willing to burn |
receiver | address | Address to receive the assets (as UnlockToken shares) |
Returns
| Name | Type | Description |
|---|---|---|
shares | uint256 | Amount of shares burned |
redeemForMinAssets
Redeems exact shares for assets or reverts if less than min assets will be withdrawn
Provides slippage protection for redemptions
function redeemForMinAssets(uint256 shares, uint256 minAssets, address receiver) external returns (uint256 assets);
Parameters
| Name | Type | Description |
|---|---|---|
shares | uint256 | Amount of shares to redeem |
minAssets | uint256 | Minimum amount of assets expected |
receiver | address | Address to receive the assets (as UnlockToken shares) |
Returns
| Name | Type | Description |
|---|---|---|
assets | uint256 | Amount of assets withdrawn |
pause
Pauses all token transfers
Only callable through AccessManager with ADMIN_ROLE
function pause() external restricted;
unpause
Unpauses all token transfers
Only callable through AccessManager with ADMIN_ROLE
function unpause() external restricted;
Structs
ApyUSDStorage
Note: storage-location: erc7201:apyx.storage.ApyUSD
struct ApyUSDStorage {
/// @notice Reference to the UnlockToken contract for unlocking delay
IUnlockToken unlockToken;
/// @notice Reference to the Vesting contract for yield distribution
IVesting vesting;
/// @notice Unlocking fee as a percentage with 18 decimals (e.g., 0.01e18 = 1%, 1e18 = 100%)
uint256 unlockingFee;
/// @notice Address to receive unlocking fees
address feeWallet;
}
CommitToken
Inherits: ERC4626, IERC7540Redeem, AccessManaged, ICommitToken, ERC20Pausable, ERC165
Title: CommitToken
ERC4626 vault with asynchronous redeem requests and cooldown periods
This contract is non-transferable as an implementation convenience for the current version. The non-transferability simplifies accounting and prevents transfer-related complexity in the async redeem request system. Future versions could support transferability if needed.
This contract implements a custom async redemption flow inspired by ERC-7540, but is NOT compliant with the ERC-7540 specification. It deviates from MUST requirements including: shares not removed from owner on request, preview functions not reverting, operator functionality not supported, and ERC-7575 share() method not implemented.
TODO: Add support for freezing
State Variables
supplyCap
Maximum total supply allowed
uint256 public supplyCap
unlockingDelay
Cooldown period for redeem requests (unlocking delay)
uint48 public unlockingDelay
redeemRequests
Mapping of user addresses to their redeem requests
mapping(address => Request) redeemRequests
denyList
Reference to the AddressList contract for deny list checking
IAddressList public denyList
Functions
constructor
Reference to the Silo contract for cooldown escrow
constructor(address authority_, address asset_, uint48 unlockingDelay_, address denyList_, uint256 supplyCap_)
AccessManaged(authority_)
ERC4626(IERC20(asset_))
ERC20(
string.concat(IERC20Metadata(asset_).name(), " Commit Token"),
string.concat("CT-", IERC20Metadata(asset_).symbol())
);
setUnlockingDelay
Sets the unlocking delay (redeem cooldown)
Only callable through AccessManager with ADMIN_ROLE
function setUnlockingDelay(uint48 newUnlockingDelay) external restricted;
Parameters
| Name | Type | Description |
|---|---|---|
newUnlockingDelay | uint48 | New unlocking delay in seconds |
setDenyList
Sets the deny list contract
Only callable through AccessManager with ADMIN_ROLE
function setDenyList(address newDenyList) external restricted;
Parameters
| Name | Type | Description |
|---|---|---|
newDenyList | address | Address of the new AddressList contract |
setSupplyCap
Sets the supply cap
Only callable through AccessManager with ADMIN_ROLE
function setSupplyCap(uint256 newSupplyCap) external restricted;
Parameters
| Name | Type | Description |
|---|---|---|
newSupplyCap | uint256 | New maximum total supply |
_revertIfDenied
function _revertIfDenied(address user) internal view;
supplyCapRemaining
Returns the remaining capacity before hitting the supply cap
function supplyCapRemaining() external view returns (uint256);
Returns
| Name | Type | Description |
|---|---|---|
<none> | uint256 | Amount of tokens that can still be minted |
pause
Pauses all token transfers
Only callable through AccessManager with ADMIN_ROLE
function pause() external restricted;
unpause
Unpauses all token transfers
Only callable through AccessManager with ADMIN_ROLE
function unpause() external restricted;
decimals
Returns the number of decimals used to get its user representation.
For example, if decimals equals 2, a balance of 505 tokens should
be displayed to a user as 5.05 (505 / 10 ** 2).
Tokens usually opt for a value of 18, imitating the relationship between
Ether and Wei. This is the default value returned by this function, unless
it's overridden.
NOTE: This information is only used for display purposes: it in
no way affects any of the arithmetic of the contract, including
{IERC20-balanceOf} and {IERC20-transfer}.
function decimals() public view override(ERC4626, ERC20) returns (uint8);
_update
Commit tokens are not transferable and only support minting and burning
Non-transferability is an implementation convenience for this version to simplify the async redeem request accounting. Future versions may support transferability.
function _update(address from, address to, uint256 value) internal override(ERC20, ERC20Pausable);
_convertToShares
Assets convert to shares at a 1:1 ratio
function _convertToShares(uint256 assets, Math.Rounding) internal pure override returns (uint256 shares);
Parameters
| Name | Type | Description |
|---|---|---|
assets | uint256 | The amount of assets to convert to shares |
<none> | Math.Rounding |
Returns
| Name | Type | Description |
|---|---|---|
shares | uint256 | The amount of shares |
_convertToAssets
Shares convert to assets at a 1:1 ratio
function _convertToAssets(uint256 shares, Math.Rounding) internal pure override returns (uint256 assets);
Parameters
| Name | Type | Description |
|---|---|---|
shares | uint256 | The amount of shares to convert to assets |
<none> | Math.Rounding |
Returns
| Name | Type | Description |
|---|---|---|
assets | uint256 | The amount of assets |
maxDeposit
Returns the maximum amount of assets that can be deposited for a receiver
Per ERC-4626, this must not revert and must return the max amount that would be accepted
function maxDeposit(address receiver) public view override returns (uint256 maxAssets);
Parameters
| Name | Type | Description |
|---|---|---|
receiver | address | The address that would receive the shares |
Returns
| Name | Type | Description |
|---|---|---|
maxAssets | uint256 | Maximum assets that can be deposited |
maxMint
Returns the maximum amount of shares that can be minted for a receiver
Per ERC-4626, this must not revert and must return the max amount that would be accepted
Since conversion is 1:1, this returns the same value as maxDeposit
function maxMint(address receiver) public view override returns (uint256 maxShares);
Parameters
| Name | Type | Description |
|---|---|---|
receiver | address | The address that would receive the shares |
Returns
| Name | Type | Description |
|---|---|---|
maxShares | uint256 | Maximum shares that can be minted |
_deposit
Deposit is only supported for the caller
function _deposit(address caller, address receiver, uint256 assets, uint256 shares)
internal
virtual
override
whenNotPaused;
Parameters
| Name | Type | Description |
|---|---|---|
caller | address | The address to deposit from |
receiver | address | The address to deposit to |
assets | uint256 | The amount of assets to deposit |
shares | uint256 | The amount of shares to deposit |
_requestRedeem
Shared functionality for requestRedeem and requestWithdraw
function _requestRedeem(Request storage request, address controller, address owner, uint256 assets, uint256 shares)
internal
virtual;
requestRedeem
Request an asynchronous redeem of shares
function requestRedeem(uint256 shares, address controller, address owner)
external
override
returns (uint256 requestId);
Parameters
| Name | Type | Description |
|---|---|---|
shares | uint256 | Amount of shares to redeem |
controller | address | Address that will control the request (must be msg.sender) |
owner | address | Address that owns the shares (must be msg.sender) |
Returns
| Name | Type | Description |
|---|---|---|
requestId | uint256 | ID of the request (always 0 for this implementation) |
requestWithdraw
Request an asynchronous withdrawal of assets
function requestWithdraw(uint256 assets, address controller, address owner) external returns (uint256 requestId);
Parameters
| Name | Type | Description |
|---|---|---|
assets | uint256 | Amount of assets to withdraw |
controller | address | Address that will control the request (must be msg.sender) |
owner | address | Address that owns the shares (must be msg.sender) |
Returns
| Name | Type | Description |
|---|---|---|
requestId | uint256 | ID of the request (always 0) |
_cooldownRemaining
function _cooldownRemaining(Request storage request) internal view returns (uint48 cooldown);
cooldownRemaining
Returns the remaining cooldown time for a request
function cooldownRemaining(uint256, address owner) external view returns (uint48 cooldown);
Parameters
| Name | Type | Description |
|---|---|---|
<none> | uint256 | |
owner | address | Address that owns the shares (must be msg.sender) |
Returns
| Name | Type | Description |
|---|---|---|
cooldown | uint48 | Remaining cooldown time in seconds |
_isClaimable
function _isClaimable(Request storage request) internal view returns (bool);
isClaimable
Returns true if a request is claimable
function isClaimable(uint256, address owner) external view returns (bool);
Parameters
| Name | Type | Description |
|---|---|---|
<none> | uint256 | |
owner | address | Address that owns the shares (must be msg.sender) |
Returns
| Name | Type | Description |
|---|---|---|
<none> | bool | true if the request is claimable, false otherwise |
pendingRedeemRequest
Returns pending redeem request amount that hasn't completed cooldown
Accepts a uint256 requestId as the first param to meet the 7540 spec
function pendingRedeemRequest(uint256, address owner) external view override returns (uint256 shares);
Parameters
| Name | Type | Description |
|---|---|---|
<none> | uint256 | |
owner | address | Address to query |
Returns
| Name | Type | Description |
|---|---|---|
shares | uint256 | Pending share amount |
claimableRedeemRequest
Returns claimable redeem request amount that has completed cooldown
Accepts a uint256 requestId as the first param to meet the 7540 spec
function claimableRedeemRequest(uint256, address owner) public view override returns (uint256 shares);
Parameters
| Name | Type | Description |
|---|---|---|
<none> | uint256 | |
owner | address | Address to query |
Returns
| Name | Type | Description |
|---|---|---|
shares | uint256 | Claimable share amount |
maxRedeem
Returns maximum redeem amount for an address
Returns claimable redeem request shares, or 0 if none
function maxRedeem(address owner) public view override returns (uint256);
_withdraw
function _withdraw(Request storage request, address caller, address receiver, address owner) internal;
redeem
Claims a pending redeem request and burns shares
Overrides ERC4626 to only work with pending requests (no instant redeems)
function redeem(uint256 shares, address receiver, address owner) public override returns (uint256 assets);
Parameters
| Name | Type | Description |
|---|---|---|
shares | uint256 | Amount of shares to claim (must match request) |
receiver | address | Address to receive the assets |
owner | address | Address that owns the shares (must be msg.sender) |
Returns
| Name | Type | Description |
|---|---|---|
assets | uint256 | Amount of assets received |
withdraw
Withdraws assets from the contract
function withdraw(uint256 assets, address receiver, address owner) public override returns (uint256 shares);
Parameters
| Name | Type | Description |
|---|---|---|
assets | uint256 | Amount of assets to withdraw |
receiver | address | Address to receive the assets |
owner | address | Address that owns the shares (must be msg.sender) |
Returns
| Name | Type | Description |
|---|---|---|
shares | uint256 | Amount of shares burned to receive assets |
setOperator
Not implemented in v0 - owner and controller must be msg.sender
Sets or removes an operator for the caller.
function setOperator(address, bool) external pure virtual returns (bool);
Parameters
| Name | Type | Description |
|---|---|---|
<none> | address | |
<none> | bool |
Returns
| Name | Type | Description |
|---|---|---|
<none> | bool | Whether the call was executed successfully or not |
isOperator
Returns true if the operator is the controller
Returns true if the operator is approved as an operator for an controller.
function isOperator(address controller, address operator) public view virtual returns (bool);
Parameters
| Name | Type | Description |
|---|---|---|
controller | address | The address of the controller. |
operator | address | The address of the operator. |
Returns
| Name | Type | Description |
|---|---|---|
<none> | bool | status The approval status |
supportsInterface
Returns true if the contract implements the interface
Does NOT claim ERC-7540 compliance via ERC-165. This contract implements a custom async redemption flow inspired by ERC-7540 but deviates from the specification.
function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool);
Parameters
| Name | Type | Description |
|---|---|---|
interfaceId | bytes4 | The interface identifier to check |
Returns
| Name | Type | Description |
|---|---|---|
<none> | bool | true if the contract implements the interface |
LinearVestV0
Inherits: AccessManaged, IVesting
Title: LinearVestV0
Contract that receives yield deposits and vests them linearly over a configurable period
Allows yield distributors to deposit yield, which vests linearly over time. Only vault contract can transfer vested yield. New deposits reset the vesting period. Features:
- Linear vesting over configurable period
- Vesting period resets on new deposits (adds to existing unvested amount)
- Only vault can transfer vested yield
- Access control via AccessManager
State Variables
asset
The asset token (apxUSD) held in vesting
IERC20 public immutable asset
vestingAmount
Total amount currently vesting, including any newlyVestedAmount() that has not yet been accrued to the fullyVestedAmount. This amount is updated on depositYield and setVestingPeriod.
To calculate the current annualizedYield() or apy() use the ApyUSDRateView contract.
uint256 public vestingAmount
fullyVestedAmount
Total amount that has been fully vested but not yet transferred to the beneficiary
uint256 public fullyVestedAmount
lastDepositTimestamp
Timestamp of the last deposit (when vesting period was reset)
uint256 public lastDepositTimestamp
lastTransferTimestamp
Timestamp of the last transfer (when vested yield was transferred to the beneficiary)
uint256 public lastTransferTimestamp
vestingPeriod
Vesting period in seconds
uint256 public vestingPeriod
beneficiary
Beneficiary contract address (authorized for transfers)
address public beneficiary
Functions
onlyBeneficiary
Ensures only vault contract can call transfer functions
This is only applied to the pullVestedYield function, so it is more efficient to inline
modifier onlyBeneficiary() ;
constructor
Initializes the LinearVestV0 contract
constructor(address _asset, address _authority, address _beneficiary, uint256 _vestingPeriod)
AccessManaged(_authority);
Parameters
| Name | Type | Description |
|---|---|---|
_asset | address | Address of the asset token (apxUSD) |
_authority | address | Address of the AccessManager contract |
_beneficiary | address | Address of the beneficiary contract |
_vestingPeriod | uint256 | Initial vesting period in seconds |
vestingPeriodStart
Returns the start of the current vesting period
function vestingPeriodStart() public view override returns (uint256);
Returns
| Name | Type | Description |
|---|---|---|
<none> | uint256 | Start of the current vesting period |
vestingPeriodEnd
Returns the end of the current vesting period
function vestingPeriodEnd() public view override returns (uint256);
Returns
| Name | Type | Description |
|---|---|---|
<none> | uint256 | End of the current vesting period |
vestingPeriodRemaining
Returns the remaining time in the current vesting period
function vestingPeriodRemaining() public view override returns (uint256);
Returns
| Name | Type | Description |
|---|---|---|
<none> | uint256 | Remaining time in the current vesting period |
vestedAmount
Returns the amount of yield that has vested and is available, including fully vested and newly vested yield.
function vestedAmount() public view override returns (uint256);
Returns
| Name | Type | Description |
|---|---|---|
<none> | uint256 | Amount of vested yield including fully vested and newly vested yield |
newlyVestedAmount
Returns the amount of yield that has been newly vested since the last transfer
function newlyVestedAmount() public view override returns (uint256);
Returns
| Name | Type | Description |
|---|---|---|
<none> | uint256 | Amount of newly vested yield |
unvestedAmount
Returns the amount of yield that is still vesting
function unvestedAmount() public view override returns (uint256);
Returns
| Name | Type | Description |
|---|---|---|
<none> | uint256 | Amount of unvested yield |
depositYield
Deposits yield into the vesting contract
Resets the vesting period, adding vested yield to the fullyVestedAmount and the new deposit amount to the vestingAmount.
function depositYield(uint256 amount) external override restricted;
Parameters
| Name | Type | Description |
|---|---|---|
amount | uint256 | Amount of yield to deposit |
pullVestedYield
Transfers all vested yield to the vault
Only callable by vault contract. No-op if no vested yield available.
function pullVestedYield() external override onlyBeneficiary;
setVestingPeriod
Sets the vesting period
Only callable through AccessManager with ADMIN_ROLE
function setVestingPeriod(uint256 newPeriod) external override restricted;
Parameters
| Name | Type | Description |
|---|---|---|
newPeriod | uint256 | New vesting period in seconds |
setBeneficiary
Sets the beneficiary address. This is used when initializing the vesting contract, to set the beneficiary address and when migrating to a new vesting contract.
Only callable through AccessManager with ADMIN_ROLE
function setBeneficiary(address newBeneficiary) external override restricted;
Parameters
| Name | Type | Description |
|---|---|---|
newBeneficiary | address | New beneficiary contract address |
MinterV0
Inherits: IMinterV0, AccessManaged, EIP712, Pausable
Title: MinterV0
Handles minting of apxUSD tokens and enforces protocol controls
Implements EIP-712 for structured data signing and delegates delay enforcement to AccessManager Features:
- Order-based minting with beneficiary signatures
- AccessManager-enforced delays for compliance
- Configurable max mint size
- Nonce tracking per beneficiary to prevent replay attacks
- EIP-712 typed structured data hashing
State Variables
apxUSD
The apxUSD token contract
ApxUSD public immutable apxUSD
nonce
Mapping of beneficiary => nonce for replay protection
mapping(address => uint48) public nonce
pendingOrders
Mapping of operationId => Order for pending mints
mapping(bytes32 => Order) internal pendingOrders
maxMintAmount
Maximum amount that can be minted in a single order
uint208 public maxMintAmount
rateLimitAmount
Maximum amount that can be minted within the rate limit period
uint256 public rateLimitAmount
rateLimitPeriod
Duration of the rate limit period in seconds (e.g., 86400 for 24 hours)
uint48 public rateLimitPeriod
mintHistory
Queue of recent mints for rate limiting (stores encoded MintRecord)
Should this be moved to it's own storage location?
DoubleEndedQueue.Bytes32Deque mintHistory
MAX_RATE_LIMIT_PERIOD
Maximum duration of the rate limit period
Mint history records are only pruned against this ceiling, not the current rateLimitPeriod. This ensures that if rateLimitPeriod is extended, historical records are still available for accurate rate limit accounting.
uint48 public constant MAX_RATE_LIMIT_PERIOD = 14 days
ORDER_TYPEHASH
EIP-712 type hash for Order struct
bytes32 public constant ORDER_TYPEHASH =
keccak256("Order(address beneficiary,uint48 notBefore,uint48 notAfter,uint48 nonce,uint208 amount)")
Functions
constructor
Initializes the MinterV0 contract
constructor(
address initialAuthority,
address _apxUSD,
uint208 _maxMintAmount,
uint208 _rateLimitAmount,
uint48 _rateLimitPeriod
) AccessManaged(initialAuthority) EIP712("ApxUSD MinterV0", "1");
Parameters
| Name | Type | Description |
|---|---|---|
initialAuthority | address | Address of the AccessManager contract |
_apxUSD | address | Address of the ApxUSD token contract |
_maxMintAmount | uint208 | Maximum amount that can be minted in a single order (e.g., 10_000e18 for $10k) |
_rateLimitAmount | uint208 | Maximum amount that can be minted within the rate limit period |
_rateLimitPeriod | uint48 | Duration of the rate limit period in seconds (e.g., 86400 for 24 hours) |
DOMAIN_SEPARATOR
Returns the EIP-712 domain separator
function DOMAIN_SEPARATOR() public view returns (bytes32);
Returns
| Name | Type | Description |
|---|---|---|
<none> | bytes32 | The domain separator for this contract |
structHashOrder
Returns the EIP-712 struct hash for an order
Returns the struct hash according to EIP-712 standard
function structHashOrder(Order calldata order) public pure returns (bytes32);
Parameters
| Name | Type | Description |
|---|---|---|
order | Order | The mint order to hash |
Returns
| Name | Type | Description |
|---|---|---|
<none> | bytes32 | The struct hash |
hashOrder
Returns the EIP-712 typed hash for an order
This returns the full EIP-712 digest that should be signed
function hashOrder(Order calldata order) public view returns (bytes32);
Parameters
| Name | Type | Description |
|---|---|---|
order | Order | The mint order to hash |
Returns
| Name | Type | Description |
|---|---|---|
<none> | bytes32 | The EIP-712 compliant digest |
validateOrder
Validates an order without executing it (reverts if invalid)
function validateOrder(Order calldata order, bytes calldata signature) public view;
Parameters
| Name | Type | Description |
|---|---|---|
order | Order | The mint order to validate |
signature | bytes | The beneficiary's signature over the order |
requestMint
Requests a mint by validating the order and scheduling with AccessManager
function requestMint(Order calldata order, bytes calldata signature)
external
restricted
whenNotPaused
returns (bytes32 operationId);
Parameters
| Name | Type | Description |
|---|---|---|
order | Order | The mint order containing beneficiary, notBefore, notAfter, nonce, and amount |
signature | bytes | The beneficiary's signature over the order |
Returns
| Name | Type | Description |
|---|---|---|
operationId | bytes32 | The unique identifier for this scheduled operation |
executeMint
Executes a scheduled mint operation via AccessManager
function executeMint(bytes32 operationId) external restricted whenNotPaused;
Parameters
| Name | Type | Description |
|---|---|---|
operationId | bytes32 | The unique identifier of the scheduled operation |
cancelMint
Cancels a scheduled mint operation
Only callable through AccessManager with MINT_GUARD_ROLE
This is critical for recovering from the 256 operation limit - expired orders must be cancelled to free up operation IDs in AccessManager
function cancelMint(bytes32 operationId) external restricted;
Parameters
| Name | Type | Description |
|---|---|---|
operationId | bytes32 | The unique identifier of the scheduled operation |
pendingOrder
Returns the details of a pending order
function pendingOrder(bytes32 operationId) public view returns (Order memory);
Parameters
| Name | Type | Description |
|---|---|---|
operationId | bytes32 | The unique identifier of the scheduled operation |
Returns
| Name | Type | Description |
|---|---|---|
<none> | Order | order The pending order details |
mintStatus
Returns the status of a mint operation
Useful for front-ends and monitoring systems to determine order state
function mintStatus(bytes32 operationId) external view returns (MintStatus);
Parameters
| Name | Type | Description |
|---|---|---|
operationId | bytes32 | The unique identifier of the operation |
Returns
| Name | Type | Description |
|---|---|---|
<none> | MintStatus | status The current status of the operation: - NotFound: Order not in storage (never existed, executed, or cancelled) - Scheduled: Order pending but not yet ready (AccessManager delay not passed or before notBefore) - Ready: Order pending and ready to execute (AccessManager delay passed, after notBefore, before notAfter) - Expired: Order pending but expired (after notAfter time) |
setMaxMintAmount
Updates the maximum mint amount
function setMaxMintAmount(uint208 newMaxMintAmount) external restricted;
Parameters
| Name | Type | Description |
|---|---|---|
newMaxMintAmount | uint208 | New maximum amount for a single mint order |
setRateLimit
Updates the rate limit configuration
function setRateLimit(uint256 newAmount, uint48 newPeriod) external restricted;
Parameters
| Name | Type | Description |
|---|---|---|
newAmount | uint256 | New maximum amount that can be minted within the rate limit period |
newPeriod | uint48 | New duration of the rate limit period in seconds |
rateLimit
Returns the current rate limit configuration
function rateLimit() external view returns (uint256 amount, uint48 period);
Returns
| Name | Type | Description |
|---|---|---|
amount | uint256 | Maximum amount that can be minted within the rate limit period |
period | uint48 | Duration of the rate limit period in seconds |
rateLimitMinted
Returns the total amount minted in the current rate limit period
Iterates from newest to oldest records and breaks early when cutoff is reached
function rateLimitMinted() public view returns (uint256);
Returns
| Name | Type | Description |
|---|---|---|
<none> | uint256 | Total amount minted in the current period |
rateLimitAvailable
Returns the amount available to mint without exceeding the rate limit
function rateLimitAvailable() public view returns (uint256);
Returns
| Name | Type | Description |
|---|---|---|
<none> | uint256 | Amount that can still be minted in the current period |
cleanMintHistory
Manually cleans up to n expired mint records from the history queue
Only callable through AccessManager with MINTER_ROLE
Useful for gas management when queue grows large
Uses MAX_RATE_LIMIT_PERIOD as the cutoff ceiling instead of rateLimitPeriod. This ensures that records are retained long enough to support any valid rateLimitPeriod value, preventing under-counting when the period is extended.
function cleanMintHistory(uint32 n) external restricted returns (uint32 cleaned);
Parameters
| Name | Type | Description |
|---|---|---|
n | uint32 | Maximum number of records to attempt cleaning |
Returns
| Name | Type | Description |
|---|---|---|
cleaned | uint32 | Number of records actually removed |
pause
Pauses the minting process
function pause() external restricted;
unpause
Unpauses the minting process
function unpause() external restricted;
_encodeOrderData
Encodes order data for AccessManager scheduling/execution
function _encodeOrderData(Order memory order) internal view returns (bytes memory);
Parameters
| Name | Type | Description |
|---|---|---|
order | Order | The order to encode |
Returns
| Name | Type | Description |
|---|---|---|
<none> | bytes | Encoded calldata with nonce appended for uniqueness |
_cleanMintHistory
Cleans expired mint records from the queue
function _cleanMintHistory() internal;
_cleanMintHistoryUpTo
Internal helper to clean up to n expired mint records from the queue
function _cleanMintHistoryUpTo(uint32 n) internal returns (uint32 cleaned);
Parameters
| Name | Type | Description |
|---|---|---|
n | uint32 | Maximum number of records to clean (type(uint32).max for unlimited) |
Returns
| Name | Type | Description |
|---|---|---|
cleaned | uint32 | Number of records actually removed |
_encodeMintRecord
Encodes mint record into bytes32: [timestamp:48][amount:208]
function _encodeMintRecord(uint48 timestamp, uint208 amount) internal pure returns (bytes32);
_decodeMintRecord
Decodes bytes32 ([timestamp:48][amount:208]) into mint record
function _decodeMintRecord(bytes32 data) internal pure returns (MintRecord memory);
RedemptionPoolV0
Inherits: IRedemptionPool, AccessManaged, Pausable, ReentrancyGuardTransient
Title: RedemptionPoolV0
Redeems asset tokens for reserve assets at a configurable exchange rate
Non-upgradeable. Uses AccessManager for role-based access; ROLE_REDEEMER for redeem(), ADMIN for deposit/withdraw/setExchangeRate/pause/unpause. Exchange rate is reserve asset per asset (1e18 = 1:1) in the precision of the asset token.
The asset MUST support burnFrom(address,uint256) as defined in ERC20Burnable.
State Variables
asset
Asset token to be redeemed (burned); e.g. apxUSD
ERC20Burnable public immutable asset
reserveAsset
Reserve asset paid out on redemption; e.g. USDC
IERC20 public immutable reserveAsset
assetHasMoreDecimals
True if asset has more decimals than reserve, false otherwise
bool private immutable assetHasMoreDecimals
decimalScalingFactor
Scaling factor for decimal conversion: 10^abs(assetDecimals - reserveDecimals)
uint256 private immutable decimalScalingFactor
exchangeRate
Exchange rate: reserve asset per asset, 1e18 = 1:1 (reserveAmount = assetsAmount * exchangeRate / 1e18)
uint256 public exchangeRate
Functions
constructor
Initializes the redemption pool
constructor(address initialAuthority, ERC20Burnable asset_, IERC20 reserveAsset_) AccessManaged(initialAuthority);
Parameters
| Name | Type | Description |
|---|---|---|
initialAuthority | address | Address of the AccessManager contract |
asset_ | ERC20Burnable | Asset token (e.g. apxUSD) |
reserveAsset_ | IERC20 | Reserve asset token (e.g. USDC) |
previewRedeem
Preview how much reserve assets would be received for a given assets amount
Does not consider pause state or reserve balance; callers should check paused() and reserveBalance() Rounding is downward in favor of the pool. Formula: reserveAmount = (assetsAmount * exchangeRate) / (1e18 * 10^(assetDecimals - reserveDecimals))
function previewRedeem(uint256 assetsAmount) public view override returns (uint256 reserveAmount);
Parameters
| Name | Type | Description |
|---|---|---|
assetsAmount | uint256 | Amount of assets to preview |
Returns
| Name | Type | Description |
|---|---|---|
reserveAmount | uint256 | Amount of reserve assets that would be received |
redeem
Redeem assets for reserve assets at the current exchange rate
Requires ROLE_REDEEMER. Burns/transfers assets and sends reserve assets
function redeem(uint256 assetsAmount, address receiver, uint256 minReserveAssetOut)
external
override
restricted
whenNotPaused
nonReentrant
returns (uint256 reserveAmount);
Parameters
| Name | Type | Description |
|---|---|---|
assetsAmount | uint256 | Amount of assets to redeem |
receiver | address | Address to receive the reserve assets |
minReserveAssetOut | uint256 | Minimum reserve assets to receive (slippage protection) |
Returns
| Name | Type | Description |
|---|---|---|
reserveAmount | uint256 | Amount of reserve assets received |
deposit
Deposit reserve assets into the contract to fund redemptions
function deposit(uint256 reserveAmount) external override restricted nonReentrant;
Parameters
| Name | Type | Description |
|---|---|---|
reserveAmount | uint256 | Amount of reserve assets to deposit |
withdraw
Withdraw excess reserve assets from the contract
Restricted to admin role
function withdraw(uint256 amount, address receiver) external override restricted;
Parameters
| Name | Type | Description |
|---|---|---|
amount | uint256 | |
receiver | address | Address to receive the reserve assets |
withdrawTokens
Withdraw excess assets from the contract
Use to recover tokens erroneously sent to the pool (e.g. asset or any other ERC20). Can also withdraw reserve asset; equivalent to withdraw() for that case.
function withdrawTokens(address withdrawAsset, uint256 amount, address receiver)
public
override
restricted
nonReentrant;
Parameters
| Name | Type | Description |
|---|---|---|
withdrawAsset | address | Address of the asset to withdraw |
amount | uint256 | Amount of the asset to withdraw |
receiver | address | Address to receive the asset |
setExchangeRate
Update the exchange rate (assets to reserve assets)
Restricted to admin role
function setExchangeRate(uint256 newRate) external override restricted;
Parameters
| Name | Type | Description |
|---|---|---|
newRate | uint256 | Reserve asset per asset, 1e18 = 1:1 |
pause
Pause redemptions
Restricted to admin role
function pause() external restricted;
unpause
Unpause redemptions
Restricted to admin role
function unpause() external restricted;
reserveBalance
Get the current reserve asset balance
function reserveBalance() public view override returns (uint256);
Returns
| Name | Type | Description |
|---|---|---|
<none> | uint256 | Reserve asset balance available for redemptions |
Roles
Title: Roles
Centralized role definitions for AccessManager-based access control
These role IDs are used across the Apyx ecosystem of contracts for consistent access management
State Variables
ADMIN_ROLE
Built-in OpenZeppelin admin role - controls all other roles and critical functions
uint64 public constant ADMIN_ROLE = 0
MINT_STRAT_ROLE
Minting strategy role - granted to minting contracts (e.g., MinterV0)
Can call PrefUSD.mint() with no execution delay
uint64 public constant MINT_STRAT_ROLE = 1
MINTER_ROLE
Individual minter role - granted to authorized minter addresses
Can call MinterV0.requestMint() and executeMint() with configured delays
uint64 public constant MINTER_ROLE = 2
MINT_GUARD_ROLE
Mint guardian role - granted to compliance guardians
Can call MinterV0.cancelMint() to stop non-compliant mint operations
uint64 public constant MINT_GUARD_ROLE = 3
YIELD_DISTRIBUTOR_ROLE
Yield distributor role - granted to addresses that can deposit yield
Can call Vesting.depositYield() to add yield for vesting
uint64 public constant YIELD_DISTRIBUTOR_ROLE = 6
ROLE_YIELD_OPERATOR
Yield operator role - granted to addresses that can trigger yield deposits
Can call YieldDistributor.depositYield() to deposit yield to vesting
uint64 public constant ROLE_YIELD_OPERATOR = 7
ROLE_REDEEMER
Redeemer role - granted to addresses that can perform redemptions
Can call RedemptionPoolV0.redeem() to burn asset and pay out reserve
uint64 public constant ROLE_REDEEMER = 8
Functions
setRoleAdmins
Sets the admin role for all roles (extension function)
function setRoleAdmins(AccessManager self) internal;
Parameters
| Name | Type | Description |
|---|---|---|
self | AccessManager | The AccessManager contract |
assignAdminTargetsFor
Assigns admin function selectors for ApxUSD contract (extension function)
function assignAdminTargetsFor(AccessManager self, ApxUSD apxUSD) internal;
Parameters
| Name | Type | Description |
|---|---|---|
self | AccessManager | The AccessManager contract |
apxUSD | ApxUSD | The ApxUSD contract |
assignAdminTargetsFor
Assigns admin function selectors for MinterV0 contract (extension function)
function assignAdminTargetsFor(AccessManager self, IMinterV0 minterContract) internal;
Parameters
| Name | Type | Description |
|---|---|---|
self | AccessManager | The AccessManager contract |
minterContract | IMinterV0 | The MinterV0 contract |
assignAdminTargetsFor
Assigns admin function selectors for ApyUSD contract (extension function)
function assignAdminTargetsFor(AccessManager self, ApyUSD apyUSD) internal;
Parameters
| Name | Type | Description |
|---|---|---|
self | AccessManager | The AccessManager contract |
apyUSD | ApyUSD | The ApyUSD contract |
assignAdminTargetsFor
Assigns admin function selectors for Vesting contract (extension function)
function assignAdminTargetsFor(AccessManager self, IVesting vestingContract) internal;
Parameters
| Name | Type | Description |
|---|---|---|
self | AccessManager | The AccessManager contract |
vestingContract | IVesting | The Vesting contract |
assignAdminTargetsFor
Assigns admin function selectors for AddressList contract (extension function)
function assignAdminTargetsFor(AccessManager self, IAddressList denyList) internal;
Parameters
| Name | Type | Description |
|---|---|---|
self | AccessManager | The AccessManager contract |
denyList | IAddressList | The AddressList contract |
assignAdminTargetsFor
Assigns admin function selectors for CommitToken contract (extension function)
function assignAdminTargetsFor(AccessManager self, CommitToken commitToken) internal;
Parameters
| Name | Type | Description |
|---|---|---|
self | AccessManager | The AccessManager contract |
commitToken | CommitToken | The CommitToken contract (or subclass like UnlockToken) |
assignAdminTargetsFor
Assigns ADMIN_ROLE function selectors for YieldDistributor contract (extension function)
function assignAdminTargetsFor(AccessManager self, IYieldDistributor yieldDistributor) internal;
Parameters
| Name | Type | Description |
|---|---|---|
self | AccessManager | The AccessManager contract |
yieldDistributor | IYieldDistributor | The YieldDistributor contract |
assignAdminTargetsFor
Assigns ADMIN_ROLE function selectors for IRedemptionPool contract (extension function)
function assignAdminTargetsFor(AccessManager self, RedemptionPoolV0 pool) internal;
Parameters
| Name | Type | Description |
|---|---|---|
self | AccessManager | The AccessManager contract |
pool | RedemptionPoolV0 | The IRedemptionPool contract |
assignAdminTargetsFor
Assigns admin function selectors for OrderDelegate contract (extension function)
function assignAdminTargetsFor(AccessManager self, OrderDelegate orderDelegate) internal;
Parameters
| Name | Type | Description |
|---|---|---|
self | AccessManager | The AccessManager contract |
orderDelegate | OrderDelegate | The OrderDelegate contract |
assignMinterTargetsFor
Assigns MINTER_ROLE function selectors for MinterV0 contract (extension function)
function assignMinterTargetsFor(AccessManager self, IMinterV0 minterContract) internal;
Parameters
| Name | Type | Description |
|---|---|---|
self | AccessManager | The AccessManager contract |
minterContract | IMinterV0 | The MinterV0 contract |
assignMintGuardTargetsFor
Assigns mint guard function selectors for MinterV0 contract (extension function)
function assignMintGuardTargetsFor(AccessManager self, IMinterV0 minterContract) internal;
Parameters
| Name | Type | Description |
|---|---|---|
self | AccessManager | The AccessManager contract |
minterContract | IMinterV0 | The MinterV0 contract |
assignMintingContractTargetsFor
Assigns minting contract function selectors for ApxUSD contract (extension function)
function assignMintingContractTargetsFor(AccessManager self, ApxUSD apxUSD) internal;
Parameters
| Name | Type | Description |
|---|---|---|
self | AccessManager | The AccessManager contract |
apxUSD | ApxUSD | The ApxUSD contract |
assignYieldDistributorTargetsFor
Assigns yield distributor function selectors for Vesting contract (extension function)
function assignYieldDistributorTargetsFor(AccessManager self, IVesting vestingContract) internal;
Parameters
| Name | Type | Description |
|---|---|---|
self | AccessManager | The AccessManager contract |
vestingContract | IVesting | The Vesting contract |
assignYieldOperatorTargetsFor
Assigns ROLE_YIELD_OPERATOR function selectors for YieldDistributor contract (extension function)
function assignYieldOperatorTargetsFor(AccessManager self, IYieldDistributor yieldDistributor) internal;
Parameters
| Name | Type | Description |
|---|---|---|
self | AccessManager | The AccessManager contract |
yieldDistributor | IYieldDistributor | The YieldDistributor contract |
assignRedeemerTargetsFor
Assigns ADMIN_ROLE and ROLE_REDEEMER function selectors for RedemptionPool contract (extension function)
function assignRedeemerTargetsFor(AccessManager self, IRedemptionPool pool) internal;
Parameters
| Name | Type | Description |
|---|---|---|
self | AccessManager | The AccessManager contract |
pool | IRedemptionPool | The RedemptionPool contract (e.g. RedemptionPoolV0) |
UnlockToken
Inherits: CommitToken, IUnlockToken
Title: UnlockToken
CommitToken subclass that allows a vault to initiate redeem requests on behalf of users
The vault address is immutable and set at construction. The vault can act as an operator for any controller, enabling it to initiate redeem requests automatically.
Like CommitToken, this version is non-transferable for implementation simplicity. Future versions may support transferability or could be implemented as an NFT to enable transferring unlocking positions between users.
Inherits CommitToken's custom async redemption flow, which is inspired by but NOT compliant with ERC-7540.
State Variables
vault
The vault address that can act as an operator (immutable)
address public immutable vault
Functions
constructor
Constructs the UnlockToken contract
constructor(address authority_, address asset_, address vault_, uint48 unlockingDelay_, address denyList_)
CommitToken(authority_, asset_, unlockingDelay_, denyList_, type(uint256).max);
Parameters
| Name | Type | Description |
|---|---|---|
authority_ | address | Address of the AccessManager contract |
asset_ | address | Address of the underlying asset token |
vault_ | address | Address of the vault that can act as an operator (immutable) |
unlockingDelay_ | uint48 | Cooldown period for redeem requests in seconds |
denyList_ | address | Address of the AddressList contract for deny list checking |
onlyVault
Ensures that only the vault can call the function
modifier onlyVault() ;
name
Returns the token name: "{VaultName} Unlock Token"
Overrides CommitToken's name() which returns "{AssetName} Commit Token"
function name() public view override(ERC20, IERC20Metadata) returns (string memory);
Returns
| Name | Type | Description |
|---|---|---|
<none> | string | The token name |
symbol
Returns the token symbol: "{AssetSymbol}unlock"
Overrides CommitToken's symbol() which returns "CT-{AssetSymbol}"
function symbol() public view override(ERC20, IERC20Metadata) returns (string memory);
Returns
| Name | Type | Description |
|---|---|---|
<none> | string | The token symbol |
isOperator
Returns true if the operator is the controller or the vault
function isOperator(address controller, address operator)
public
view
override(CommitToken, IERC7540Operator)
returns (bool);
Parameters
| Name | Type | Description |
|---|---|---|
controller | address | The controller address |
operator | address | The operator address to check |
Returns
| Name | Type | Description |
|---|---|---|
<none> | bool | true if operator is controller or vault, false otherwise |
_deposit
Overrides CommitToken _deposit to restrict access to vault only
Only the vault can deposit assets into the UnlockToken
function _deposit(address caller, address receiver, uint256 assets, uint256 shares) internal override onlyVault;
Parameters
| Name | Type | Description |
|---|---|---|
caller | address | The address to deposit from |
receiver | address | The address to deposit to |
assets | uint256 | The amount of assets to deposit |
shares | uint256 | The amount of shares to deposit |
_requestRedeem
Overrides CommitToken _requestRedeem to restrict access to vault only
Only the vault can request redeem on behalf of users
function _requestRedeem(Request storage request, address controller, address owner, uint256 assets, uint256 shares)
internal
override
onlyVault;
Parameters
| Name | Type | Description |
|---|---|---|
request | Request | The redeem request storage pointer |
controller | address | Address that will control the request |
owner | address | Address that owns the shares |
assets | uint256 | Amount of assets to redeem |
shares | uint256 | Amount of shares to redeem |
YieldDistributor
Inherits: AccessManaged, ERC1271Delegated, IYieldDistributor, ReentrancyGuardTransient
Title: YieldDistributor
Contract that receives yield from MinterV0 minting operations and deposits it to the Vesting contract
Acts as an intermediary between MinterV0 and Vesting. When minting operations have YieldDistributor as the beneficiary, it receives apxUSD tokens. Operators can then trigger deposits of these tokens to the Vesting contract for vesting. This decouples the Minting and Vesting contracts while allowing for yield distribution to be automated. Features:
- Receives apxUSD tokens from MinterV0 minting operations
- Operator-controlled yield deposits to Vesting. This can be an automated service.
- Admin-controlled vesting contract configuration
- Access control via AccessManager
State Variables
asset
The apxUSD token contract
IERC20 public immutable asset
vesting
The vesting contract address
IVesting public vesting
Functions
constructor
Initializes the YieldDistributor contract
constructor(address _asset, address _authority, address _vesting, address _signingDelegate)
AccessManaged(_authority)
ERC1271Delegated(_signingDelegate);
Parameters
| Name | Type | Description |
|---|---|---|
_asset | address | Address of the apxUSD token contract |
_authority | address | Address of the AccessManager contract |
_vesting | address | Address of the Vesting contract |
_signingDelegate | address | Address of the signature delegate |
availableBalance
Returns the available balance of apxUSD tokens
function availableBalance() external view returns (uint256);
Returns
| Name | Type | Description |
|---|---|---|
<none> | uint256 | Amount of apxUSD tokens available for deposit |
setVesting
Sets the vesting contract address
Only callable through AccessManager with ADMIN_ROLE
function setVesting(address newVesting) external restricted;
Parameters
| Name | Type | Description |
|---|---|---|
newVesting | address | New vesting contract address |
setSigningDelegate
Sets the signature delegate
Only callable through AccessManager with ADMIN_ROLE
function setSigningDelegate(address newSigningDelegate) external restricted;
Parameters
| Name | Type | Description |
|---|---|---|
newSigningDelegate | address | New signature delegate address |
depositYield
Deposits yield to the vesting contract
Only callable through AccessManager with ROLE_YIELD_OPERATOR Approves vesting contract and calls depositYield() which pulls tokens
function depositYield(uint256 amount) external restricted;
Parameters
| Name | Type | Description |
|---|---|---|
amount | uint256 | Amount of yield to deposit |
withdraw
Withdraws yield from the vesting contract
Only callable through AccessManager with ADMIN_ROLE
function withdraw(uint256 amount, address receiver) external override restricted;
Parameters
| Name | Type | Description |
|---|---|---|
amount | uint256 | Amount of yield to withdraw |
receiver | address | Address to receive the yield |
withdrawTokens
Withdraws tokens from the YieldDistributor
Only callable through AccessManager with ADMIN_ROLE
function withdrawTokens(address withdrawAsset, uint256 amount, address receiver)
public
override
restricted
nonReentrant;
Parameters
| Name | Type | Description |
|---|---|---|
withdrawAsset | address | Address of the asset to withdraw |
amount | uint256 | Amount of the asset to withdraw |
receiver | address | Address to receive the asset |