yWAPE is a yield-bearing ERC20 wrapper for native tokens, specifically designed for APE. It allows users to deposit native tokens and receive shares that automatically accrue yield through the ApeChain's Nitro Native Yield module. The contract implements the WETH9 interface while adding yield-bearing capabilities.
- Automatic Yield Distribution: Integrates with the Nitro Native Yield module to automatically distribute yield to all token holders proportional to their share ownership
- Share-Based System: Uses a share-based accounting system where tokens represent a proportional claim on the total underlying balance
- Standard ERC20 Interface: Fully compatible with ERC20 standard, enabling integration with existing DeFi protocols
- Flexible Deposits: Supports direct deposits through native token transfers and deposits on behalf of other addresses
- Multiple Withdrawal Options: Allows partial and complete withdrawals with options to specify recipient addresses
The contract uses a share-based system to track ownership of the underlying native tokens. Two key conversion functions manage this:
-
_nativeToShares
: Calculates shares to mint for a given native token deposit- For the first deposit, shares = native amount
- Subsequently, shares = (native_amount * total_supply) / (total_balance - native_amount)
-
_sharesToNative
: Calculates native tokens to return for a given share amount- Native amount = (shares * total_balance) / total_supply
This system ensures:
- Fair distribution of yield across all token holders
- Protection against share price manipulation
- Accurate accounting of deposits and withdrawals
The contract provides three ways to deposit:
- Direct transfer to contract address (using
receive()
) - Standard
deposit()
function - Delegated
deposit(address to)
function for third-party deposits
Users can withdraw their tokens through:
withdraw(uint256 wad)
: Partial withdrawal to callerwithdraw(address dst, uint256 wad)
: Partial withdrawal to specified addresswithdrawAll()
: Complete withdrawal of caller's balance
- Revert on zero deposits (
ZeroDeposit
error) - Revert on withdrawals to zero address (
ZeroAddress
error) - Revert on failed withdrawals (
WithdrawalFailed
error) - Protected share calculations to handle edge cases (empty contract)
// Deposit by sending native tokens directly
address(wape).call{value: 1 ether}("");
// Or use the deposit function
wape.deposit{value: 1 ether}();
wape.deposit{value: 1 ether}(recipientAddress);
// Withdraw specific amount
wape.withdraw(shareAmount);
// Withdraw all balance
wape.withdrawAll();
// Withdraw to different address
wape.withdraw(recipientAddress, shareAmount);
- The contract inherits from audited implementations (Solady's ERC20)
- Share calculations are designed to prevent rounding exploits
- Share-modifying functions include implicit reentrancy protections
- Native token handling follows established patterns from WETH9
sequenceDiagram
participant User
participant Other as Other Address
participant WAPE as yWAPE Contract
participant Nitro as Nitro Native Yield
Note over WAPE: Contract Deployment
activate WAPE
WAPE->>Nitro: configureAutomaticYield()
deactivate WAPE
Note over Nitro,WAPE: Continuous Yield Stream
activate Nitro
loop Every Block
Nitro-->>WAPE: Stream native yield
Note over WAPE: Contract balance grows, all shares grow in value
end
Note over User,Nitro: Deposit Flows
User->>+WAPE: deposit() {value: nativeAmount}
WAPE->>WAPE: _nativeToShares()
WAPE->>WAPE: _mint()
WAPE-->>User: Deposit Event
deactivate WAPE
User->>+WAPE: deposit(otherAddress) {value: nativeAmount}
WAPE->>WAPE: _nativeToShares()
WAPE->>WAPE: _mint(otherAddress)
WAPE-->>User: Deposit Event
deactivate WAPE
Note over User,Nitro: Direct Transfer
User->>+WAPE: send native tokens
WAPE->>WAPE: receive()
WAPE->>WAPE: _deposit()
WAPE-->>User: Deposit Event
deactivate WAPE
Note over User,Nitro: Withdrawal Flows
User->>+WAPE: withdraw(shares)
WAPE->>WAPE: _sharesToNative()
Note over WAPE: Native amount includes<br/>accumulated yield
WAPE->>WAPE: _burn()
WAPE->>User: transfer native tokens
WAPE-->>User: Withdrawal Event
deactivate WAPE
User->>+WAPE: withdraw(otherAddress, shares)
WAPE->>WAPE: _sharesToNative()
Note over WAPE: Native amount includes<br/>accumulated yield
WAPE->>WAPE: _burn()
WAPE->>Other: transfer native tokens
WAPE-->>User: Withdrawal Event
deactivate WAPE
User->>+WAPE: withdrawAll()
WAPE->>WAPE: _withdraw(msg.sender, balance)
Note over WAPE: Native amount includes<br/>accumulated yield
WAPE->>User: transfer all native tokens
WAPE-->>User: Withdrawal Event
deactivate WAPE
deactivate Nitro
This contract is licensed under GPL-3.0. See the LICENSE for more details.