Skip to main content
← Oracle Tier Evidence

MaplePool (SyrupUSDC / USDC)

Oracle deep-dive for 0x80ac24aa929eaf5013f6436cda2a7ba190f5cc0b — Maple Finance pool share token.

  • Source: ERC-4626 Vault (MaplePool)
  • Pair: SyrupUSDC / USDC
  • Score: 0.2
  • Tier: Very High Risk
  • Slug: erc4626_eth_syrupusdc_usdc

Contract Architecture

MaplePool is an ERC-4626 vault where the share token (SyrupUSDC) represents a claim on USDC held in Maple's lending pool. The exchange rate derives from totalAssets() / totalSupply(), where totalAssets() is sourced from the external manager contract.

The pair is SyrupUSDC / USDC (not SyrupUSDC / USD) because the vault's underlying asset is USDC — convertToAssets() returns USDC amounts, not USD.

Risk Dimensions

DimensionObservationImpact
Governance / adminEvery action gated by checkCall(functionId) -> IPoolManagerLike(manager).canCall(...)Centralization / policy risk
External dependencytotalAssets() and unrealizedLosses() sourced from manager contractShare price depends on external accounting
Redemption mechanicsprocessRedeem/processWithdraw, escrow params, exit windows via WithdrawalManagerNot "always redeem at NAV" — queue/window/escrow layer
Loss socializationconvertToExitAssets/convertToExitShares subtracts unrealizedLosses()NAV drops on credit losses
Transfer restrictionstransfer/transferFrom gated by checkCallPermissioned transfers (whitelist, KYC, sanctions)
UpgradeabilityPool deployer controls implementationManager can alter pool behavior

Code Anchors

Permission gating — every state-mutating function routes through:

modifier checkCall(uint32 functionId) {
require(IPoolManagerLike(manager).canCall(functionId, msg.sender), "NOT_AUTHORIZED");
_;
}

This means deposits, withdrawals, and transfers are all policy-gated. The pool manager contract is the single point of authority.

Manager dependencytotalAssets() delegates to the manager:

function totalAssets() public view returns (uint256) {
return IPoolManagerLike(manager).totalAssets();
}

The share price is entirely determined by what the manager reports. If the manager contract is upgraded or its accounting logic changes, the exchange rate changes with it.

Loss-aware exit math — redemptions subtract unrealized losses:

function convertToExitAssets(uint256 shares_) public view returns (uint256) {
uint256 assets_ = convertToAssets(shares_);
uint256 losses_ = IPoolManagerLike(manager).unrealizedLosses();
return assets_ - (assets_ * losses_ / totalAssets());
}

This means the effective redemption rate is lower than the accounting rate during periods of credit loss. An oracle using convertToAssets() would overstate the realizable value.

Transfer restrictionstransfer and transferFrom are gated:

function transfer(address to_, uint256 amount_) checkCall(TRANSFER) { ... }

Tokens cannot be freely transferred without pool manager approval. This limits secondary market price discovery.

Practical Guidance

As oracle base (score 0.2): Very high risk. The exchange rate is accounting-driven, manager-controlled, and loss-adjusted. Not suitable as a primary oracle reference.

As collateral: Conservative haircuts required. The redemption rate differs from the accounting rate during loss events, and exit is mediated through queues and escrow windows — not instant.

Monitoring triggers:

  • unrealizedLosses() increasing (credit deterioration)
  • Manager contract upgrade events
  • WithdrawalManager parameter changes (cooldown, window duration)
  • totalAssets() diverging from expected accrual trajectory