> ## Documentation Index
> Fetch the complete documentation index at: https://getequity.io/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Ethereum (Base) — Trading

> The Market and token functions you call to quote, buy, sell, and claim payouts on Base.

Everything you need to trade lives on two contracts: **`Market`** (quotes + `buy`/`sell`)
and the **RWA token** itself (ERC-20 balance/approve + payouts). The functions below are
the trader-facing subset — admin/governance functions are intentionally omitted.

## Market — quotes & trading

```solidity theme={null}
interface IMarket {
    struct AssetConfig {
        address token;          // ERC20 RWA token
        address vault;          // Vault holding payment tokens
        uint256 price;          // Price in cents per 1 token (PRICE_PRECISION = 100)
        uint256 feeBps;         // Fee in basis points (100 = 1%)
        bool    isActive;       // Whether trading is enabled
        uint256 lastUpdated;    // Timestamp of last price update
        uint8   tokenDecimals;  // Cached token decimals
    }

    // ---- Discover & read ----
    function getRegisteredTokens() external view returns (address[] memory);
    function isAssetTradeable(address token) external view returns (bool);   // registered && active
    function getAsset(address token) external view returns (AssetConfig memory);

    // ---- Quote (call before trading) ----
    function calculateBuyCost(address token, uint256 amount)
        external view returns (uint256 baseCost, uint256 fee, uint256 totalCost);
    function calculateSellPayout(address token, uint256 amount)
        external view returns (uint256 grossPayout, uint256 fee, uint256 netPayout);

    // ---- Trade ----
    function buy(address token, uint256 amount, uint256 maxCost) external;    // maxCost = slippage guard
    function sell(address token, uint256 amount, uint256 minPayout) external; // minPayout = slippage guard
}
```

## RWA token — balances, approvals & terms

The token is a standard ERC-20 (18 decimals) plus a few reads for the asset terms.

> [!WARNING]
>
> **There are no coupon payments.** Yield accrues into the Market price instead — see
> [How yield accrues](#how-yield-accrues). `hasPeriodicPayouts()` still exists on the
> contract and returns `payoutFrequency != NONE`, but **no payment happens on any
> schedule**; treat it as a descriptive label, not as behaviour. The former
> `calculatePayout()` and `claimPayout()` functions have been removed.

```solidity theme={null}
interface IRWAToken {
    // ---- ERC-20 ----
    function decimals() external view returns (uint8);            // 18
    function balanceOf(address account) external view returns (uint256);
    function allowance(address owner, address spender) external view returns (uint256);
    function approve(address spender, uint256 amount) external returns (bool);
    function transfer(address to, uint256 amount) external returns (bool);

    // ---- Asset info ----
    function payoutToken() external view returns (address);       // settlement currency
    function hasMaturity() external view returns (bool);
    function maturityDate() external view returns (uint256);      // 0 if none
    function paused() external view returns (bool);               // trading/transfers paused?

    // ---- Yield ----
    // Yield is carried by the Market price, not by this token. There is nothing to claim.
    function interestRateBps() external view returns (uint256);   // declared rate; restated on a reset
                                                                  // (the Market's rate is what accrues)
    function redeemPrincipal() external returns (uint256);        // after maturity, self-service
}
```

> [!NOTE]
>
> `payoutToken()` also tells you which ERC-20 you'll spend when buying and receive when
> selling — it's the asset's settlement currency.

## Buying

1. **Quote** the cost with `calculateBuyCost(token, amount)`.
2. **Approve** the payment token to the `Market` for at least `totalCost`.
3. **Buy** with a `maxCost` guard.

```js theme={null}
// ethers v6 — amount is in token base units (18 decimals)
const amount = 100n * 10n ** 18n; // 100 tokens

const [ , , totalCost] = await market.calculateBuyCost(token, amount);
const maxCost = totalCost + totalCost / 100n; // allow 1% slippage

const payToken = await rwaToken.payoutToken();
const pay = new ethers.Contract(payToken, erc20Abi, signer);
await (await pay.approve(marketAddress, maxCost)).wait();

await (await market.buy(token, amount, maxCost)).wait();
```

## Selling

1. **Quote** the proceeds with `calculateSellPayout(token, amount)`.
2. **Approve** the RWA token to the `Market` for `amount`.
3. **Sell** with a `minPayout` guard.

```js theme={null}
const amount = 100n * 10n ** 18n;

const [ , , netPayout] = await market.calculateSellPayout(token, amount);
const minPayout = netPayout - netPayout / 100n; // allow 1% slippage

await (await rwaToken.approve(marketAddress, amount)).wait();

await (await market.sell(token, amount, minPayout)).wait();
```

## How yield accrues

**Your balance never changes, and nothing is ever pushed to you.** Interest is carried by
the asset's price on the Market, which rises every second at the contractual rate:

```
price(t) = checkpointPrice x (1 + rateBps / 10000 x elapsed / 365 days)
```

So a holding is worth `balance x price`, and that figure grows continuously without any
transaction. Accrual **stops at maturity** — a matured note does not keep earning.

Read the value with the Market, not the token:

```js theme={null}
// What the asset is worth per whole token, in hundredths of its payoutToken.
const price = await market.currentPrice(token);

// What you would ACTUALLY receive for `amount`, net of fees. Prefer this for display:
// it is exact, whereas currentPrice() is rounded to whole hundredths.
const [gross, fee, net] = await market.calculateSellPayout(token, amount);
```

> [!WARNING]
>
> `currentPrice()` is rounded down to whole hundredths of the payout token. On a
> low-priced asset that figure can sit unchanged for weeks while the value genuinely
> accrues — a 1.00 note at 16.5% takes about 22 days to move by one hundredth. The
> underlying accrual is carried at far finer precision and **is** paid in full; only this
> display value is rounded. Use `calculateSellPayout` when the number matters.

There are two ways to realise the accrued value:

1. **Sell on the Market** at any time, at the accreted price less the asset's fee.
2. **Redeem at maturity**, if the asset has one.

## Redemption at maturity

Redemption is **self-service — you must call it yourself.** Nothing is pushed to you
automatically. It pays principal plus all accrued interest in one transfer, gross, with no
fee charged at maturity:

```js theme={null}
if (await rwaToken.hasMaturity()) {
  const maturity = await rwaToken.maturityDate();       // unix seconds
  if (BigInt(Math.floor(Date.now() / 1000)) > maturity) {
    await (await rwaToken.redeemPrincipal()).wait();     // burns your balance, pays out
  }
}
```

`redeemPrincipal()` returns `0` and does nothing if the asset has no maturity — funds and
equity are perpetual, so for those, selling on the Market is the only exit.

Separately, the issuer may wind an asset down before maturity. That path burns every
holder and pays out at a single snapshot price; you do not need to call anything for it,
and trading is halted when it begins.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.