IETokenWithWhitelist

Public Functions

whitelist

function whitelist() external view returns (contract ILPWhitelist)

WEToken

Wraps the rebasing EToken into a non-rebasing ERC-4626 vault token with static balances. 1 WEToken (share) is worth 1 eToken at the eToken's initial scale ({ETKLib.SCALE_INITIAL}). As the EToken accrues yield, each WEToken becomes redeemable for more eTokens.

The conversion between eTokens (assets) and WETokens (shares) uses {IEToken-getCurrentScale}: shares = assets * _shareScale / scale assets = shares * scale / _shareScale where _shareScale = SCALE_INITIAL * 10**decimals (computed at construction) normalizes the share unit so that 1 WEToken = 1 eToken when the eToken has no accrued returns. If the underlying eToken has a whitelist, this contract's address must be whitelisted.

Variables

WAD

uint256 WAD

SCALE_INITIAL

uint256 SCALE_INITIAL

Initial scale of the underlying eToken (see {ETKLib.SCALE_INITIAL}), in WAD.

_shareScale

uint256 _shareScale

Factor that maps 1 eToken base unit (at the initial scale) to WEToken base units.

SCALE_INITIAL * 10**(WEToken decimals - eToken decimals). For an eToken with 6 decimals this equals 1e26: at the initial scale, shares = assets * 1e26 / 1e14 = assets * 1e12, so 1 eToken (1e6) wraps into exactly 1 WEToken (1e18).

freezer

address freezer

Address authorized to call {setFrozen}. If address(0), anyone may call it but the freeze is always validated against the eToken's whitelist (open-freeze / cache mode). Can be changed by the owner via {setFreezer}.

frozen

mapping(address => bool) frozen

Tracks frozen accounts; frozen accounts cannot transfer WETokens out

When the eToken has a whitelist, this acts as a cache of whatever is enabled or not for the eToken. An account can't be frozen unless it can't transfer out normal eTokens (checked from the whitelist), and can't be unfrozen unless it CAN transfer out normal eTokens.

Events

AccountFrozen

event AccountFrozen(address account, bool frozen)

Emitted when an account is frozen or unfrozen

FreezerChanged

event FreezerChanged(address oldFreezer, address newFreezer)

Emitted when the freezer address is changed by the owner

Errors

FrozenAccount

error FrozenAccount(address account)

Thrown when a transfer is attempted from a frozen account

NotFreezer

error NotFreezer()

Thrown when {setFrozen} is called by an unauthorized address (freezer is set and caller is not the freezer)

FrozenStateMismatch

error FrozenStateMismatch(address user, bool whitelistFrozen, bool newFrozenState)

Thrown when the requested frozen state conflicts with the eToken whitelist's sendTransfer decision

NoWhitelistConfigured

error NoWhitelistConfigured()

Thrown when freezer is address(0) and the eToken has no whitelist to validate against

InvalidAssetDecimals

error InvalidAssetDecimals(uint8 decimals)

Thrown when the underlying eToken has more than 18 decimals (can't be represented in the share scale)

Public Functions

constructor

constructor(contract IEToken eToken_, string name_, string symbol_, address freezer_, address owner_) public

Parameters

Name Type Description
eToken_ contract IEToken The underlying rebasing EToken to wrap
name_ string Name for the wrapped token
symbol_ string Symbol for the wrapped token
freezer_ address Initial address authorized to freeze/unfreeze accounts. Use address(0) for open freeze mode (anyone can call, validated against the eToken's whitelist).
owner_ address Initial owner, authorized to change the freezer via {setFreezer}.

decimals

function decimals() public pure returns (uint8)

_Decimals are computed by adding the decimal offset on top of the underlying asset's decimals. This "original" value is cached during construction of the vault contract. If this read operation fails (e.g., the asset has not been created yet), a default of 18 is used to represent the underlying asset's decimals.

See {IERC20Metadata-decimals}._

setFreezer

function setFreezer(address newFreezer) external

Updates the authorized freezer address.

Parameters

Name Type Description
newFreezer address The new freezer. Use address(0) to switch to open-freeze / cache mode.

setFrozen

function setFrozen(address user, bool frozen_) external

Freezes or unfreezes an account.

Caller must be the freezer or, when freezer is address(0), anyone may call. The eToken's whitelist is always consulted when it is configured: freezing requires the whitelist to reject the user's sendTransfer; unfreezing requires it to accept. When there is no whitelist, the call only succeeds if freezer != address(0) (an authorized freezer may act without a whitelist, but open-freeze mode requires one).

Parameters

Name Type Description
user address The account to freeze or unfreeze.
frozen_ bool True to freeze, false to unfreeze.

Private Functions

_convertToShares

function _convertToShares(uint256 assets, enum Math.Rounding rounding) internal view returns (uint256)

Uses the eToken scale directly rather than the totalAssets/totalSupply ratio.

_convertToAssets

function _convertToAssets(uint256 shares, enum Math.Rounding rounding) internal view returns (uint256)

Uses the eToken scale directly rather than the totalAssets/totalSupply ratio.

_update

function _update(address from, address to, uint256 value) internal

Blocks any share movement where from is frozen (transfers and burns). Deposit (mint: from == address(0)) is already gated by the eToken's safeTransferFrom — a blacklisted user's eToken transfer will revert at the eToken level. Burns (redeem/withdraw) must also be blocked: ERC-4626 allows an arbitrary receiver, so a frozen owner could otherwise drain their underlying eTokens to another address.

_setFreezer

function _setFreezer(address newFreezer) internal