Vault.sol¶
The vault contract holds all user funds with per-user ledger tracking. It separates asset custody from trading logic.
Why the Vault Exists¶
The vault enables continuous trading without a wallet transaction for every fill. Without it, every order fill would require an on-chain token transfer, meaning traders would pay gas on every trade. With the vault, users deposit once and their balance is tracked as a per-user ledger balance. Fills settle through ledger updates, so traders can keep placing and filling orders without signing a new wallet transaction for each fill.
This is critical for professional market makers and financial institutions who place hundreds or thousands of orders per day. Without the vault, each fill would require its own token movement. The vault lets them deposit collateral once, then trade continuously while paying gas for deposit and withdrawal transactions.
Mainnet: 0xC7d4Fd2638e6630C8C61329878676b88A8A24D43 Source: src/Vault.sol
Functions¶
deposit¶
Pull tokens from a user's wallet into the vault.
| Parameter | Type | Description |
|---|---|---|
user | address | Beneficiary account |
token | address | ERC-20 token address |
amount | uint256 | Amount to deposit |
Requirements:
- Caller must have
TRADER_ROLE - User must not be blacklisted
- Amount must be > 0
- User must have approved the vault to spend the token
The active TRADER_ROLE holder is the Sera contract.
Events:
creditLedger¶
Credit a user's vault balance. The caller must have already transferred tokens to the vault in the same transaction.
| Parameter | Type | Description |
|---|---|---|
user | address | Beneficiary account |
token | address | ERC-20 token address |
expectedAmount | uint256 | Amount to credit |
withdraw¶
Debit a user's vault balance and transfer tokens to a recipient.
| Parameter | Type | Description |
|---|---|---|
user | address | Account being debited |
token | address | ERC-20 token address |
amount | uint256 | Amount to withdraw |
to | address | Token recipient |
Requirements:
tomust not be the zero address- Amount must be > 0
- User balance must be sufficient
Events:
transferLedger¶
Vault balance transfer between two users. No ERC-20 token movement occurs.
| Parameter | Type | Description |
|---|---|---|
fromUser | address | Source account |
toUser | address | Destination account |
token | address | ERC-20 token address |
amount | uint256 | Amount to transfer |
This is used internally during order settlement. The total vault TVL remains constant.
Events:
event Withdrawn(address indexed token, address indexed user, uint256 amount); // fromUser
event Deposited(address indexed token, address indexed user, uint256 amount); // toUser
Both events are emitted to keep standard subgraph indexers in sync with the ledger move, even though no ERC-20 transfer actually happens.
balanceOf¶
Query a user's vault balance for a specific token.
Query the total physical ERC-20 balance held in the vault:
setBlacklisted¶
Blacklist or unblacklist a user account.
Blacklisted users cannot deposit or receive credits, but can still withdraw their existing balance.
Events:
isBlacklisted¶
Check if a user is blacklisted.
rescueToken¶
Rescue tokens that were accidentally sent directly to the vault (not through deposit).
Can only rescue surplus tokens (physical balance minus tracked balance). User-tracked funds cannot be rescued.
Errors¶
| Error | Cause |
|---|---|
BlacklistedUser | User is blacklisted (deposits/credits blocked) |
ZeroAmount | Amount is 0 |
ZeroAddress | Recipient or user is the zero address |
InsufficientBalance | User doesn't have enough balance |
CannotRescueTrackedFunds | Attempted to rescue tracked user funds |
InsufficientSurplus | Rescue amount exceeds surplus |