Skip to main content

FewMorphoRouter Technical Reference

This page documents the external API of FewMorphoRouter based on the current contract implementation.

State Variables and Public Getters

The router exposes these public state variables:

VariableTypeDescription
morphoIMorphoImmutable Morpho Blue core contract used by all market flows
owneraddressRouter owner
guardianaddressPause-only guardian
pausedboolGlobal pause flag for user-facing functions
isSupportedWrappermapping(address => bool)Wrapper whitelist
isSupportedVaultmapping(address => bool)Vault whitelist
isSupportedMarketmapping(bytes32 => bool)Market whitelist

Because these variables are public, Solidity automatically generates getter functions:

  • morpho() returns (address)
  • owner() returns (address)
  • guardian() returns (address)
  • paused() returns (bool)
  • isSupportedWrapper(address) returns (bool)
  • isSupportedVault(address) returns (bool)
  • isSupportedMarket(bytes32) returns (bool)

Contract Construction

constructor(address morpho_, address owner_)

Creates a new router instance and stores the immutable Morpho address.

ItemDescription
morpho_Address of the Morpho Blue contract
owner_Initial router owner
ReturnsNone

Fails when:

  • morpho_ == address(0)
  • owner_ == address(0)

External Dependencies

The router relies on a small set of external interfaces.

IFewWrappedToken

Few wrapper tokens are expected to support:

FunctionPurpose
token()Returns the underlying token address
wrap(uint256 assets)Pulls underlying and mints wrapped tokens
unwrap(uint256 assets)Burns wrapped tokens and returns underlying

IERC4626

Vault integrations depend on standard ERC4626 entrypoints:

FunctionPurpose
asset()Returns the vault asset address
deposit(uint256 assets, address receiver)Deposits vault assets and mints shares
withdraw(uint256 assets, address receiver, address owner)Burns shares and withdraws assets
redeem(uint256 shares, address receiver, address owner)Redeems shares for assets

Admin Functions

setOwner(address newOwner)

Updates the router owner.

ItemDescription
newOwnerNew owner address
ReturnsNone

Fails when:

  • caller is not the current owner
  • newOwner == address(0)
  • newOwner == owner

setGuardian(address newGuardian)

Updates the pause-only guardian role.

ItemDescription
newGuardianNew guardian address
ReturnsNone

Fails when:

  • caller is not the owner
  • newGuardian == guardian

pause()

Pauses all user-facing business functions.

ItemDescription
ParametersNone
ReturnsNone

Fails when:

  • caller is neither owner nor guardian
  • router is already paused

unpause()

Unpauses the router.

ItemDescription
ParametersNone
ReturnsNone

Fails when:

  • caller is not the owner
  • router is not paused

setSupportedWrapper(address wrapper, bool newIsSupported)

Adds or removes a wrapper from the wrapper whitelist.

ItemDescription
wrapperWrapper token address
newIsSupportedDesired whitelist status
ReturnsNone

Fails when:

  • caller is not the owner
  • newIsSupported matches the current whitelist value

setSupportedVault(address vault, bool newIsSupported)

Adds or removes a vault from the vault whitelist.

ItemDescription
vaultERC4626 vault address
newIsSupportedDesired whitelist status
ReturnsNone

Fails when:

  • caller is not the owner
  • newIsSupported matches the current whitelist value

setSupportedMarket(bytes32 marketId, bool newIsSupported)

Adds or removes a Morpho market from the market whitelist.

ItemDescription
marketIdMorpho market id
newIsSupportedDesired whitelist status
ReturnsNone

Fails when:

  • caller is not the owner
  • newIsSupported matches the current whitelist value

rescueToken(address token, address to, uint256 amount)

Transfers tokens out of the router in paused state.

ItemDescription
tokenToken to rescue
toRecipient address
amountAmount to transfer
ReturnsNone

Fails when:

  • caller is not the owner
  • router is not paused
  • to == address(0)
  • token transfer fails

Market Functions

supplyCollateralWithWrap(bytes32 marketId, address wrapper, uint256 underlyingAmount) returns (uint256)

Supplies collateral into Morpho after wrapping the user's underlying token.

ItemDescription
marketIdTarget Morpho market
wrapperFew wrapped token used as market collateral
underlyingAmountAmount of underlying token to transfer and wrap
ReturnsWrapped collateral amount supplied

Fails when:

  • router is paused
  • reentrancy guard is triggered
  • underlyingAmount == 0
  • wrapper is not whitelisted
  • wrapper has no code
  • wrapper.token() is zero or has no code
  • marketId is not whitelisted
  • Morpho market does not exist
  • market collateral token does not equal wrapper
  • ERC20 transfer, approval, wrap, or Morpho call fails

borrowAndUnwrap(bytes32 marketId, address wrapper, uint256 borrowAssets) returns (uint256 assetsBorrowed, uint256 sharesBorrowed)

Borrows wrapped assets from Morpho, unwraps them, and sends the underlying token to the caller.

ItemDescription
marketIdTarget Morpho market
wrapperFew wrapped token used as market loan token
borrowAssetsWrapped asset amount to borrow
assetsBorrowedActual asset amount borrowed
sharesBorrowedBorrow shares opened in Morpho

Fails when:

  • router is paused
  • reentrancy guard is triggered
  • borrowAssets == 0
  • wrapper is not whitelisted
  • wrapper has no code
  • wrapper.token() is zero or has no code
  • marketId is not whitelisted
  • Morpho market does not exist
  • market loan token does not equal wrapper
  • borrow, unwrap, or final transfer fails

repayWithWrap(bytes32 marketId, address wrapper, uint256 underlyingAmount) returns (uint256 assetsRepaid, uint256 sharesRepaid)

Wraps the user's underlying token and repays a Morpho borrow position.

ItemDescription
marketIdTarget Morpho market
wrapperFew wrapped token used as market loan token
underlyingAmountUnderlying token amount to transfer and wrap
assetsRepaidActual asset amount repaid
sharesRepaidBorrow shares repaid

Fails when:

  • router is paused
  • reentrancy guard is triggered
  • underlyingAmount == 0
  • wrapper is not whitelisted
  • wrapper has no code
  • wrapper.token() is zero or has no code
  • marketId is not whitelisted
  • Morpho market does not exist
  • market loan token does not equal wrapper
  • ERC20 transfer, approval, wrap, or Morpho repay fails

withdrawCollateralAndUnwrap(bytes32 marketId, address wrapper, uint256 collateralAssets) returns (uint256)

Withdraws wrapped collateral from Morpho, unwraps it, and returns the underlying token.

ItemDescription
marketIdTarget Morpho market
wrapperFew wrapped token used as market collateral token
collateralAssetsWrapped collateral amount to withdraw
ReturnsUnderlying asset amount sent back to the user

Fails when:

  • router is paused
  • reentrancy guard is triggered
  • collateralAssets == 0
  • wrapper is not whitelisted
  • wrapper has no code
  • wrapper.token() is zero or has no code
  • marketId is not whitelisted
  • Morpho market does not exist
  • market collateral token does not equal wrapper
  • withdraw, unwrap, or final transfer fails

Vault Functions

vaultDepositWithWrap(address vault, address wrapper, uint256 underlyingAmount) returns (uint256 shares)

Wraps underlying tokens and deposits the wrapped asset into a vault.

ItemDescription
vaultTarget ERC4626 vault
wrapperFew wrapped token expected by the vault
underlyingAmountUnderlying token amount to transfer and wrap
sharesVault shares minted to the user

Fails when:

  • router is paused
  • reentrancy guard is triggered
  • underlyingAmount == 0
  • wrapper is not whitelisted
  • wrapper has no code
  • wrapper.token() is zero or has no code
  • vault is not whitelisted
  • vault has no code
  • vault.asset() != wrapper
  • ERC20 transfer, approval, wrap, or vault deposit fails

vaultWithdrawAndUnwrap(address vault, address wrapper, uint256 assets) returns (uint256 shares)

Withdraws wrapped vault assets, unwraps them, and transfers underlying tokens to the user.

ItemDescription
vaultTarget ERC4626 vault
wrapperFew wrapped token expected by the vault
assetsWrapped vault asset amount to withdraw
sharesVault shares burned during withdrawal

Fails when:

  • router is paused
  • reentrancy guard is triggered
  • assets == 0
  • wrapper is not whitelisted
  • wrapper has no code
  • wrapper.token() is zero or has no code
  • vault is not whitelisted
  • vault has no code
  • vault.asset() != wrapper
  • vault withdrawal, unwrap, or final transfer fails

vaultRedeemAndUnwrap(address vault, address wrapper, uint256 shares) returns (uint256 assets)

Redeems vault shares, unwraps the returned wrapped assets, and sends underlying tokens to the user.

ItemDescription
vaultTarget ERC4626 vault
wrapperFew wrapped token expected by the vault
sharesVault shares to redeem
assetsWrapped assets redeemed before unwrapping

Fails when:

  • router is paused
  • reentrancy guard is triggered
  • shares == 0
  • wrapper is not whitelisted
  • wrapper has no code
  • wrapper.token() is zero or has no code
  • vault is not whitelisted
  • vault has no code
  • vault.asset() != wrapper
  • vault redeem, unwrap, or final transfer fails

Events

The contract emits these admin and recovery events:

  • SetOwner(address newOwner)
  • SetGuardian(address newGuardian)
  • SetPaused(bool newPaused)
  • SetSupportedWrapper(address wrapper, bool newIsSupported)
  • SetSupportedVault(address vault, bool newIsSupported)
  • SetSupportedMarket(bytes32 marketId, bool newIsSupported)
  • RescueToken(address token, address to, uint256 amount)

Router-Specific Error Strings

FewMorphoRouter uses router-local error strings from RouterErrorsLib in addition to reverts propagated from Morpho, wrappers, vaults, and ERC20 transfers.

ErrorMeaning
pausedRouter is paused, or rescueToken was called while not paused
reentrancyReentrant call detected
not owner or guardianCaller is neither owner nor guardian
unsupported wrapperWrapper is not whitelisted
unsupported vaultVault is not whitelisted
unsupported marketMarket is not whitelisted
invalid wrapper underlyingWrapper returned an invalid underlying token
invalid market sideWrapper does not match the expected loan or collateral side
invalid vault assetVault asset does not equal the provided wrapper
approve revertedLow-level token approval reverted
approve returned falseToken approval returned false

Notes on Upstream Reverts

Several functions also depend on external contracts and can revert with upstream errors from:

  • Morpho Blue
  • Few wrapped token contracts
  • ERC4626 vaults
  • ERC20 token transfers and approvals

In practice, integrations should treat the router checks above as the first layer of validation, not the only source of failure.

Internal Validation and Approval Helpers

These helpers are not part of the external ABI, but they explain several observable revert paths.

_validateWrapper(address wrapper)

Checks that:

  • wrapper is whitelisted
  • wrapper is a contract
  • IFewWrappedToken(wrapper).token() returns a non-zero contract address

Returns the wrapper's underlying token address.

_validateVault(address vault, address wrapper)

Checks that:

  • vault is whitelisted
  • vault is a contract
  • IERC4626(vault).asset() == wrapper

_validateMarket(bytes32 marketId, address wrapper, bool loanSide)

Checks that:

  • marketId is whitelisted
  • Morpho.idToMarketParams(marketId) resolves to an existing market
  • if loanSide == true, then market.loanToken == wrapper
  • if loanSide == false, then market.collateralToken == wrapper

Returns the resolved Morpho market parameters.

_approveMaxIfNeeded(address token, address spender, uint256 amount)

Implements lazy approval behavior:

  • if current allowance is already at least amount, no approval is sent
  • otherwise the router resets approval to 0
  • then sets approval to type(uint256).max

This behavior exists to support tokens that require zeroing allowance before setting a new value.

_approve(address token, address spender, uint256 amount)

Performs the low-level approval call used by _approveMaxIfNeeded.

Fails when:

  • the token call reverts
  • the token returns false

On this page