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 dependency — totalAssets() 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 restrictions — transfer 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