You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
A tokenized vault system for the zOPAL token, enabling users to deposit stablecoins and receive zOPAL tokens, redeem zOPAL tokens back for underlying assets, and stake USDC to earn Zocta Points.
Price feed with tolerance checks and decimal conversion
contracts/PriceOracle.sol
Token Contracts
Contract
Description
Location
zOPAL.sol
ERC20 token with mint, burn, pause, and blacklist
contracts/zOPAL/zOPAL.sol
zOPALDepositVault.sol
zOPAL-specific deposit vault
contracts/zOPAL/zOPALDepositVault.sol
zOPALStakingVault.sol
USDC staking vault with lock periods and FIFO withdrawals
contracts/zOPAL/zOPALStakingVault.sol
zOPALStakingVaultRoles.sol
Role definitions for staking vault
contracts/zOPAL/zOPALStakingVaultRoles.sol
Access Control
Contract
Description
Location
ZothAccessControl.sol
Role-based access control for vaults
contracts/access/ZothAccessControl.sol
FunctionsAccessControl.sol
Role-based access for oracle operations
contracts/access/FunctionsAccessControl.sol
Blacklistable.sol
Blacklist functionality
contracts/access/Blacklistable.sol
Greenlistable.sol
Greenlist/whitelist functionality
contracts/access/Greenlistable.sol
Pausable.sol
Pause functionality with per-function granularity
contracts/access/Pausable.sol
Utility Contracts
Contract
Description
Location
UpgradeTimelock.sol
TimelockController for gated contract upgrades
contracts/utils/UpgradeTimelock.sol
TransparentUpgradeableProxy.sol
Proxy for upgradeable contracts
contracts/utils/TransparentUpgradeableProxy.sol
Abstract Contracts
Contract
Description
Location
ManageableVault.sol
Base vault with token management, fees, limits
contracts/abstract/ManageableVault.sol
ManageableVaultRedeem.sol
Base redemption vault functionality
contracts/abstract/ManageableVaultRedeem.sol
WithSanctionsList.sol
Chainalysis sanctions integration
contracts/abstract/WithSanctionsList.sol
ZothInitializable.sol
Base initializable for upgradeable contracts
contracts/abstract/ZothInitializable.sol
Libraries
Contract
Description
Location
DecimalsCorrectionLibrary.sol
Decimal conversion utilities (base18)
contracts/libraries/DecimalsCorrectionLibrary.sol
Interfaces
Interface
Description
IDepositVault.sol
Deposit vault interface
IRedemptionVault.sol
Redemption vault interface
IManageableVault.sol
Base vault interface
IZToken.sol
zOPAL token interface
IDataFeed.sol
Price feed interface
IVaultShared.sol
Shared types and events
IzOPALStakingVault.sol
Staking vault interface with deposit/withdrawal structs
Staking Vault
The zOPALStakingVault allows users to deposit USDC, which is converted to zOPAL via the deposit vault and transferred to an MPC wallet. Users earn Zocta Points off-chain during the lock period.
How It Works
Deposit: User deposits USDC (min 10 USDC). The vault calls instantDeposit on the zOPAL Deposit Vault, converting USDC to zOPAL, which is sent to the MPC wallet.
Lock Period: Deposits are locked for a configurable duration (default 180 days). Each deposit is tracked individually with its own lock expiry.
Withdrawal Request: User requests a withdrawal amount. The vault processes deposits in FIFO order — expired deposits first (no penalty), then locked deposits (with early withdrawal penalty).
Approval/Rejection: A vault admin reviews and approves or rejects the withdrawal request.
Settlement: On approval, net USDC (after any penalties) is transferred to the user. Penalties go to the fee receiver.
All contract upgrades are gated by an UpgradeTimelock (OpenZeppelin TimelockController). This introduces a mandatory delay between scheduling and executing an upgrade, giving users time to review changes and exit if they disagree.
# Deployer private key (without 0x prefix)DEPLOYER_ACCOUNT_PRIV_KEY=your_private_key_here# RPC URLsBASE_RPC_URL=https://mainnet.base.orgBASE_SEPOLIA_RPC_URL=https://sepolia.base.org# API keys for verificationETHERSCAN_API_KEY=your_etherscan_api_key# Tenderly (optional)TENDERLY_KEY=your_tenderly_key
Testing
Running Tests
# Run all tests
pnpm test# Run specific test file
npx hardhat test test/PriceOracle.test.ts
# Run with gas reporting
REPORT_GAS=true pnpm test# Run with coverage
npx hardhat coverage
Test Structure
test/
├── PriceOracle.test.ts # Price oracle test suite
├── DepositRedemptionFlow.test.ts # End-to-end deposit and redemption flows
├── VaultOracleIntegration.test.ts # Vault + oracle integration tests
├── Greenlist.test.ts # Greenlist/whitelist functionality
├── SanctionsAndBlacklist.test.ts # Sanctions, blacklist, and state transitions
├── EmergencyControls.test.ts # Pause/unpause and emergency operations
├── ProxyUpgrade.test.ts # Proxy upgrade pattern tests
├── FiatRedemptionApproval.test.ts # Fiat redemption approval workflow
├── NativeDecimalScaling.test.ts # Decimal conversion edge cases
├── zOPALStakingVault.test.ts # Staking vault full test suite
└── TimelockUpgrade.test.ts # Timelock upgrade flow with role checks
Role assignments, schedule/delay/execute flow, cancel, initializeV2, state preservation
Writing New Tests
import{expect}from"chai";import{ethers}from"hardhat";import{loadFixture}from"@nomicfoundation/hardhat-network-helpers";describe("ContractName",function(){asyncfunctiondeployFixture(){const[deployer]=awaitethers.getSigners();// Deploy contractsreturn{ contract, deployer };}beforeEach(asyncfunction(){constfixture=awaitloadFixture(deployFixture);// Set up test state});describe("Feature",function(){it("Should do something",asyncfunction(){// Test implementation});});});
Deployment
Deployment Scripts
Scripts are located in the deploy/ directory and execute in order:
Order
Script
Tag
Description
00
00-deploy-access-control.ts
ZothAccessControl
Deploys access control contract
01
01-deploy-zopal-token.ts
zOPAL
Deploys zOPAL token
02
02-deploy-price-oracle.ts
PriceOracle
Deploys price oracle
03
03-deploy-zopal-deposit-vault.ts
zOPALDepositVault
Deploys deposit vault
04
04-deploy-zopal-redemption-vault.ts
RedemptionVault
Deploys redemption vault
05
05-deploy-all.ts
Complete
Orchestrates full deployment
06
06-deploy-timelock.ts
UpgradeTimelock
Deploys UpgradeTimelock with role config
07
07-deploy-zopal-staking-vault.ts
zOPALStakingVault
Deploys zOPAL staking vault
NPM Scripts
# Deploy to local hardhat network
pnpm deploy:local
# Deploy to Polygon Amoy testnet
pnpm deploy:amoy
# Deploy to Polygon mainnet
pnpm deploy:mainnet
# Deploy to Base mainnet
pnpm deploy:base
# Deploy to Base Sepolia testnet
pnpm deploy:baseSepolia
# Deploy specific contracts
pnpm deploy:access-control # Only ZothAccessControl
pnpm deploy:zopal # Only zOPAL token
pnpm deploy:oracle # Only PriceOracle
pnpm deploy:deposit-vault # Only zOPALDepositVault
pnpm deploy:redemption-vault # Only RedemptionVault
pnpm deploy:all # Full deployment with orchestration# Start local node
pnpm node
# Clean artifacts
pnpm clean