Appearance
Smart Contracts ​
Deployed Addresses (SEI Mainnet) ​
USDC Vault ​
| Contract | Address |
|---|---|
| KanaVault | 0x1B85248a30C0A61DD52933C17c989d1B9aFDf98e |
| USDCStrategy | 0xdD02a58a3515e78691260Ee3ed0ca87a540A8Dc2 |
| USDC | 0xe15fC38F6D8c56aF07bbCBe3BAf5708A2Bf42392 |
| Takara cUSDC | 0xd1E6a6F58A29F64ab2365947ACb53EfEB6Cc05e0 |
| Network | SEI mainnet (chain ID 1329) |
WSEI Vault ​
| Contract | Address |
|---|---|
| SEIVault | TBD |
| SEIStrategy | TBD |
| WSEI | TBD |
| Takara cWSEI | TBD |
| Feather vault | TBD |
| Network | SEI mainnet (chain ID 1329) |
KanaVault ​
The core vault contract implementing the ERC-4626 tokenized vault standard.
SEIVault
SEIVault is functionally identical to KanaVault — the same contract instantiated with WSEI as the underlying asset and kSEI as the share token. All functions, access control, and behavior described below apply equally to SEIVault.
Key Functions ​
| Function | Description |
|---|---|
deposit(uint256 assets, address receiver) | Deposit underlying asset, receive vault shares |
withdraw(uint256 assets, address receiver, address owner) | Burn vault shares, receive underlying asset |
redeem(uint256 shares, address receiver, address owner) | Burn exact shares, receive underlying asset |
totalAssets() | Total underlying asset managed (idle + deployed) |
setStrategy(IStrategy newStrategy) | Migrate to a new strategy (owner only) |
harvest(uint256[] calldata minAmountsOut) | Claim and compound yield with slippage protection |
setKeeper(address keeper) | Set keeper address (owner only) |
revokeKeeper() | Revoke keeper access (owner only) |
setGuardian(address guardian) | Set guardian address (owner only) |
pause() | Pause all operations (guardian or owner) |
unpause() | Unpause operations (owner only) |
setFeeRecipient(address recipient) | Update fee recipient (owner only, only if not locked) |
lockFeeRecipient() | Permanently lock fee recipient (owner only, irreversible) |
Share Accounting ​
shares = deposit_amount × total_shares / total_assets
assets = shares × total_assets / total_sharesAs yield accrues, totalAssets() increases while totalShares stays constant, making each share worth more over time.
Virtual Share Offset ​
The vault uses a decimalsOffset of 6 (1e6 virtual shares/assets) to prevent inflation attacks where an attacker could donate assets to manipulate share prices and steal from subsequent depositors. This is an OpenZeppelin recommended pattern for ERC-4626 vaults.
Performance Fee ​
The vault charges a 10% performance fee (1000 basis points) on harvested yield. This fee is immutable and cannot be changed. When harvest is called, 10% of the profit is minted as additional vault shares to the fee recipient.
Withdrawal Handling ​
The vault handles protocol rounding in withdrawals by adjusting the withdrawal amount to the actual balance available. If a protocol returns slightly less than requested (due to rounding), the vault transfers the actual amount rather than reverting.
Access Control ​
| Role | Permissions |
|---|---|
| Owner | Set strategy, set keeper, set guardian, set fee recipient (if not locked), pause/unpause |
| Keeper | Trigger harvest |
| Guardian | Pause in emergencies |
| Strategy | Report yield, request funds |
| Anyone | Deposit, withdraw, view balances |
IStrategy Interface ​
The interface that all strategies must implement:
solidity
interface IStrategy {
function deposit(uint256 amount) external;
function withdraw(uint256 amount) external returns (uint256);
function harvest() external returns (uint256);
function balanceOf() external view returns (uint256);
function asset() external view returns (address);
}| Function | Description |
|---|---|
deposit(uint256) | Receive underlying asset from vault, deploy to protocols |
withdraw(uint256) | Pull underlying asset from protocols, return to vault |
harvest() | Claim rewards, compound yield (interface compatibility, no slippage protection) |
balanceOf() | Total underlying asset value across all positions |
asset() | The managed asset address (USDC for USDCStrategy, WSEI for SEIStrategy) |
Note: The strategy also implements an overloaded harvest(uint256[] calldata minAmountsOut) function for slippage protection, but this is not part of the base IStrategy interface.
USDCStrategy ​
The multi-protocol strategy for the USDC vault with dynamic yield sources and dynamic DEX router registry.
Yield sources: Yei Finance (Aave V3), Takara (Compound), Morpho (P2P).
Dynamic Yield Sources ​
Unlike previous versions with hardcoded protocol allocations, the v3 strategy uses a dynamic yield sources system that supports up to 10 protocols:
| Function | Description |
|---|---|
addYieldSource(...) | Add a new yield source (owner only) |
removeYieldSource(uint256 index) | Remove a yield source (owner only) |
updateYieldSourceSplit(uint256 index, uint256 newSplit) | Update allocation split for a source (owner only) |
enableYieldSource(uint256 index, bool enabled) | Enable/disable a yield source (owner only) |
Maximum yield sources: 10 (MAX_YIELD_SOURCES)
Split management:
- Allocations are set in basis points (total must equal 10,000)
- Example:
[4000, 3500, 2500]= 40% / 35% / 25% - Split changes have a 1-hour cooldown to prevent excessive rebalancing
Dynamic DEX Router Registry ​
The strategy maintains a registry of DEX routers for reward token swaps:
| Function | Description |
|---|---|
addRouter(address, RouterType, string label) | Add a new DEX router (owner only) |
removeRouter(uint256 index) | Remove a router (owner only) |
setActiveRouterIndex(uint256 index) | Switch active router (owner only) |
Supported router types:
- V2: Uniswap V2-style routers (e.g., DragonSwap)
- V3: Uniswap V3-style routers (e.g., Sailor)
Deposit Logic ​
On deposit, USDC is split according to current allocation weights and supplied to each enabled protocol.
Withdrawal Logic ​
On withdrawal, funds are pulled proportionally from all enabled protocols:
withdrawal_from_source = amount × source_balance / total_balanceThe strategy handles Compound rounding by transferring the minimum of the requested amount and the actual balance available after withdrawal.
Harvest ​
The recommended harvest function includes slippage protection:
solidity
function harvest(
uint256[] calldata minAmountsOut // Min USDC from each yield source's reward swaps
) external returns (uint256 profit);Harvest flow:
- Claims rewards from all enabled yield sources
- Swaps non-USDC rewards to USDC via the active DEX router with slippage protection
- Reports total yield to vault (vault takes 10% performance fee)
- Redeposits compounded USDC across protocols
Slippage protection: If the actual swap output is less than the specified minAmountOut for any source, the transaction reverts.
Array length: The minAmountsOut array must have exactly the same length as the number of yield sources.
Rebalance ​
solidity
function rebalance() external;Withdraws all funds from protocols and redeploys according to current splits. Subject to a 1-hour cooldown.
Security Features ​
| Feature | Description |
|---|---|
| ReentrancyGuard | All state-changing functions protected |
| Pausable | Guardian can pause in emergencies |
| Guardian role | Can pause but not withdraw funds |
| Slippage cap | Maximum 10% slippage (MAX_SLIPPAGE_CEILING) |
| Rebalance cooldown | 1 hour minimum between rebalances |
| Splits cooldown | 1 hour minimum between split changes |
| Max yield sources | Cap of 10 protocols |
Emergency Functions ​
rescueToken: Recover stuck tokens (owner only)
solidity
function rescueToken(address token, uint256 amount) external onlyOwner;For the vault's underlying asset, can only recover loose tokens not deployed to protocols.
Access Control ​
| Role | Permissions |
|---|---|
| Owner | Full admin control: manage yield sources, routers, splits, pause/unpause, rescue tokens |
| Keeper | Trigger harvest, rebalance, claim rewards |
| Guardian | Pause in emergencies |
| Vault | Deposit, withdraw |
SEIStrategy ​
The multi-protocol strategy for the WSEI vault. Functionally identical to USDCStrategy — same architecture, same functions, same security features — but configured with WSEI as the underlying asset and Feather (MetaMorpho ERC-4626 vault) as the third yield source instead of Morpho P2P.
Yield sources: Yei Finance (Aave V3), Takara (Compound), Feather (MetaMorpho ERC-4626).
Feather Integration ​
Unlike Morpho P2P which uses direct lending pool interaction, Feather is itself an ERC-4626 vault. The strategy deposits WSEI into Feather and receives Feather vault shares. Yield is earned through share value appreciation rather than P2P matching or reward tokens.
Because Feather is ERC-4626, the harvest step for the Feather yield source may not need a reward swap — yield is already denominated in WSEI (via share appreciation). The minAmountsOut entry for the Feather source will typically be 0 unless Feather emits separate reward tokens.
All other SEIStrategy functions, access control, and security features are identical to USDCStrategy.