Creamfinance crTokens and the underlying exchange rate
Creamfinance crTokens represent supplied assets through a conversion rate denominated in each market's underlying asset. Multiplying a crToken balance by that rate gives the corresponding underlying balance, after accounting for token precision. For a market with outstanding crTokens, the rate reflects cash plus borrows minus reserves, divided by crToken supply. That accounting value includes loans still outstanding; it does not establish how much the market can immediately return or whether a legacy market permits withdrawals.
Updated ·Cash, debt and reserves behind each crToken
The exchange rate divides the market's net underlying accounting balance among its outstanding crTokens. Every component describes the same asset market and accounting state.
For nonzero crToken supply, the exchange rate equals cash plus total borrows minus total reserves, divided by total crToken supply. The cash, borrow and reserve quantities use the underlying asset's units. The denominator counts receipt tokens, so the quotient expresses underlying units per crToken once precision is aligned.
Cash and outstanding loans
Cash is underlying currency the market currently holds. Total borrows records assets borrowers owe, including interest already accrued into that total. An ordinary borrow reduces cash while increasing total borrows by the same principal amount. Considering that principal movement alone, cash plus borrows stays unchanged. Immediate withdrawal capacity can therefore fall without a corresponding reduction in the accounting balance each crToken represents.
Reserves and supplier backing
Total reserves records the underlying amount the protocol has set aside in that market. Subtracting it excludes those reserves from supplier backing. A market's gross cash balance and the net quantity attributable to crTokens consequently answer different questions.
Outstanding receipt tokens
The supply denominator counts outstanding crTokens in that contract. It does not count CREAM tokens or sum deposits across the platform. Both the numerator and denominator must come from the same market; combining totals from different deployments produces no meaningful per-token claim.
How does the exchange rate change a wallet balance?
A wallet's underlying balance can grow while its crToken count stays unchanged, because interest changes how much underlying each receipt token represents within that market. With no mint, redemption or transfer affecting the wallet, a higher exchange rate increases its underlying claim. The increase belongs to the conversion factor, so the receipt-token count alone cannot show accumulated lending interest.
Interest accrual and the reserve factor
Interest accrual increases recorded borrowing and allocates a share of that interest to reserves, leaving the remainder in the accounting backing suppliers' crTokens.
The elapsed-block calculation
In the documented BSC base contract, accrual calculates elapsed blocks since the market's last checkpoint. It applies the market's borrow rate to outstanding borrows over that interval. The update changes borrows, reserves and the borrow index together. Interest for elapsed blocks enters stored accounting when the accrual function runs. The contract does not independently write a new balance during every block.
The share entering reserves
The reserve factor applies to accrued borrower interest. It does not take that percentage from the supplier's entire deposit. A different factor changes how new interest divides between reserves and supplier backing. The factor and rate model belong to the selected market, so neither supplies a permanent platform-wide return.
Stored values and accrued values
A stored exchange-rate read uses existing market accounting, while an accrued read includes the interest update its implementation performs before calculating the ratio. In the documented BSC base contract,
exchangeRateStored()
calculates the ratio using market cash and recorded borrow and reserve totals when crToken supply is nonzero. With zero supply, it returns the configured initial rate. It does not call
accrueInterest()
. Its name describes the absence of a new accrual step; it does not mean the function returns an archived rate.
In the documented BSC implementation,
exchangeRateCurrent()
calls
accrueInterest()
before returning the exchange rate.
An off-chain call can simulate this calculation without persisting its state changes. A transaction can persist the update. Neither form redeems crTokens or moves underlying assets into the wallet.
Contract readings for different balance questions
The contract separates the wallet's receipt-token count, its converted underlying amount and market cash. Selecting a read changes what the number describes without initiating a withdrawal.
| Reading | Returned measure | Calculation scope | Interpretation limit |
|---|---|---|---|
balanceOf(account)
|
crToken base units | One account's receipt-token count | Does not express interest growth as additional crTokens |
balanceOfUnderlying(account)
|
Underlying base units | Account crTokens converted at an accrued rate | Reports a balance without transferring underlying |
exchangeRateStored()
|
Scaled conversion factor | Existing market accounting | Does not accrue elapsed interest |
exchangeRateCurrent()
|
Scaled conversion factor | Market accounting after accrual | A calculation does not guarantee redemption |
getCash()
|
Underlying base units | Cash the market holds | Excludes assets still recorded as borrows |
| Reconciliation requires a consistent block and accrual basis for readings from the same contract. | |||
Token precision and integer arithmetic
A contract's raw exchange-rate integer needs its fixed-point scale and the decimal precision of both tokens to become a readable conversion. The BSC base contract scales its raw-unit conversion factor by
10^18
. Its balance calculation follows
underlyingRaw = crTokenRaw * exchangeRateMantissa / 10^18
, with integer truncation. The final display then divides
underlyingRaw
by the underlying asset's decimal scale.
The crToken count shown in a wallet has already applied that token's own decimal precision. Applying a raw mantissa directly to that displayed count can mix incompatible units. Token decimals belong to the individual contracts; neither the asset name nor the size of the returned integer supplies them. Display rounding can also hide small changes present in the underlying integer accounting.
Minted crTokens and the amount actually supplied
Minting converts the underlying amount credited to the market into new crTokens at the applicable exchange rate, with the implementation's integer rounding. The rate determines the receipt-token quantity. A smaller crToken count than the number of supplied underlying tokens does not, by itself, indicate a loss: the balances use different units.
The BSC
CWrappedNative
implementation bases minting on the amount its transfer helper actually receives. On its wrapped-token transfer path, the helper measures the contract's balance increase. A token transfer fee can make that increase smaller than the requested amount. For native input, the helper wraps the call's native value. This behavior describes that implementation's paths; it does not establish support for tokens with transfer fees in every market.
Redemption inputs and the quantity the contract calculates
The redemption methods fix different sides of the same conversion: one specifies receipt tokens, while the other specifies an amount of the underlying asset.
A receipt-token quantity
With
redeem(redeemTokens)
, the argument denotes crToken base units. The conversion multiplies that quantity by the applicable exchange rate to calculate the underlying transfer amount. This method addresses a receipt-token balance, so interpreting its argument as underlying units changes the requested operation.
An underlying quantity
With
redeemUnderlying(redeemAmount)
, the argument denotes underlying base units. Dividing that amount by the exchange rate determines the crTokens the implementation removes. Both methods remain subject to the account's available crTokens, market cash and applicable permission checks. Integer arithmetic can leave small differences from a rounded display calculation.
Collateral headroom and cash constrain redemption
A valid conversion can exceed the amount a market can currently return, because redemption also requires sufficient cash and permission to remove the receipt tokens. For an ordinary collateral-backed account, withdrawing from an entered collateral market must pass the Comptroller's liquidity check. An unentered market bypasses that particular check in the documented BSC controller. Cash availability and the account's actual crToken balance still matter.
Historical restrictions on redeeming a recorded claim
A calculated crToken balance cannot establish whether a particular deployment currently permits redemption, especially when its market history includes a suspension or transfer restriction. C.R.E.A.M. Finance's post-mortem published on October 31, 2021 reported suspended interactions with Ethereum v1 markets and locked crToken transfers. It identified Ethereum v1 as the affected lending deployment, distinguishing Iron Bank and other v1 markets.
The exchange-rate calculation does not settle current withdrawal availability for those legacy contracts. It also supplies no recovery allocation or confirmation of a reopened withdrawal route. A quoted underlying balance becomes redeemable only where the contract permits the operation and holds the necessary cash.
Still have questions?
What conversion applies when a market has no outstanding crTokens?
The documented BSC base contract uses its configured initialExchangeRateMantissa when totalSupply is zero. This avoids dividing by an empty supply denominator. The starting rate is a contract parameter, so an empty market does not establish a universal one-to-one conversion between a crToken and its underlying asset.
Does a successful CErc20 mint return the number of crTokens minted?
The documented CErc20 mint interface returns success status code 0 for a successful call. The underlying amount supplied and the resulting receipt-token quantity are separate data. A zero return code identifies successful execution without saying how many crTokens the account received.
Can protocol reserve withdrawals change the crToken exchange rate?
The reserve transfer alone leaves the exchange rate unchanged when cash and recorded reserves fall by the same amount. The documented BSC mechanism makes that paired reduction on a successful admin withdrawal. Interest accrual during the same transaction can separately change the rate, so a before-and-after difference need not come from the reserve transfer.
How do crToken transfers affect the market's total supply?
A permitted crToken transfer reallocates existing receipt tokens without changing the market's total crToken supply. The sender's balance falls and the recipient's balance rises. Market-wide exchange-rate accounting remains separate from that ownership change, although interest accrual or other operations can change the rate independently.
Is a larger underlying balance proof of a dollar profit?
A larger underlying balance does not establish a profit measured in dollars. The exchange rate counts units of the underlying asset; its dollar valuation also needs that asset's price. Measuring a position's profit additionally requires its deposit, withdrawal and transfer history, including the values of those cash flows.
Does balanceOfUnderlying subtract my outstanding loan?
balanceOfUnderlying reports the underlying equivalent of the account's crToken balance without subtracting its borrowing. In the documented BSC base contract, borrowBalanceCurrent addresses an account's debt separately. A net position calculation needs both sides, with each market's underlying units and any cross-asset valuation kept consistent.
Are higher crToken exchange rates evidence of better returns across markets?
A higher crToken exchange rate does not establish a higher return across different markets. Starting exchange rates can differ across markets, while raw integers also reflect token precision. Return comparisons need rate changes over a common interval and a consistent denomination. Two isolated conversion levels omit that time dimension.