Files
agent-skills/ctf-operations.md
2026-02-19 21:29:35 +05:30

181 lines
5.8 KiB
Markdown

# CTF Operations
The **Conditional Token Framework (CTF)** creates ERC1155 tokens for market outcomes. Three core operations: split, merge, redeem.
## Token Model
Every binary market has two tokens:
| Token | Redeems for | Condition |
|-------|-------------|-----------|
| **Yes** | $1.00 USDC.e | Event occurs |
| **No** | $1.00 USDC.e | Event does not occur |
Every Yes/No pair is backed by exactly $1.00 USDC.e locked in the CTF contract.
## Split
Convert USDC.e into a full set of outcome tokens.
```
$100 USDC.e → 100 Yes tokens + 100 No tokens
```
### Prerequisites
1. USDC.e balance on Polygon
2. USDC.e approval for CTF contract
3. Condition ID of the market (the condition must already be prepared on the CTF contract via `prepareCondition`)
### Function: `splitPosition`
| Parameter | Type | Value |
|-----------|------|-------|
| `collateralToken` | IERC20 | `0x2791Bca1f2de4661ED88A30C99A7a9449Aa84174` (USDC.e) |
| `parentCollectionId` | bytes32 | `0x0000...0000` (32 zero bytes) |
| `conditionId` | bytes32 | Market's condition ID |
| `partition` | uint[] | `[1, 2]` for binary (Yes=1, No=2) |
| `amount` | uint256 | Amount of USDC.e to split |
## Merge
Convert a full set of outcome tokens back to USDC.e. Inverse of split.
```
100 Yes tokens + 100 No tokens → $100 USDC.e
```
### Prerequisites
1. Equal amounts of both Yes and No tokens
2. Condition ID (the condition must already be prepared on the CTF contract via `prepareCondition`)
3. Sufficient gas for the transaction
### Function: `mergePositions`
Same parameters as split. Burns one unit of each position per unit of collateral returned.
## Redeem
Exchange winning tokens for USDC.e after market resolution.
```
Market resolves YES:
100 Yes tokens → $100 USDC.e
100 No tokens → $0
```
### Prerequisites
1. Market must be resolved
2. Hold winning tokens
3. Know the condition ID
### Function: `redeemPositions`
| Parameter | Type | Value |
|-----------|------|-------|
| `collateralToken` | IERC20 | USDC.e address |
| `parentCollectionId` | bytes32 | `0x0000...0000` |
| `conditionId` | bytes32 | Market's condition ID |
| `indexSets` | uint[] | `[1, 2]` — redeems both (only winner pays) |
Redemption burns your **entire** token balance for the condition — no amount parameter. No deadline — winning tokens are always redeemable.
### Payout Vectors
| Outcome | Payout Vector | Redemption |
|---------|---------------|------------|
| Yes wins | `[1, 0]` | Yes = $1, No = $0 |
| No wins | `[0, 1]` | Yes = $0, No = $1 |
## Contract Addresses
| Contract | Address | Purpose |
|----------|---------|---------|
| CTF | `0x4D97DCd97eC945f40cF65F87097ACe5EA0476045` | Token storage and operations |
| USDC.e (Bridged USDC) | `0x2791Bca1f2de4661ED88A30C99A7a9449Aa84174` | Collateral token |
| CTF Exchange | `0x4bFb41d5B3570DeFd03C39a9A4D8dE6Bd8B8982E` | Standard market trading |
| Neg Risk CTF Exchange | `0xC5d563A36AE78145C45a50134d48A1215220f80a` | Neg risk market trading |
| Neg Risk Adapter | `0xd91E80cF2E7be2e162c6513ceD06f1dD0dA35296` | Neg risk conversions |
## Approval Matrix
Before trading or CTF operations, the funder must approve the relevant contracts:
| Operation | Contract to Approve | Token |
|-----------|-------------------|-------|
| Buy order (standard) | CTF Exchange | USDC.e |
| Sell order (standard) | CTF Exchange | Conditional tokens |
| Buy order (neg risk) | Neg Risk CTF Exchange | USDC.e |
| Sell order (neg risk) | Neg Risk CTF Exchange | Conditional tokens |
| Split | CTF | USDC.e |
| Neg risk conversion | Neg Risk Adapter | Conditional tokens |
## Standard vs Neg Risk Markets
| Feature | Standard Markets | Neg Risk Markets |
|---------|-----------------|------------------|
| CTF Contract | ConditionalTokens | ConditionalTokens |
| Exchange Contract | CTF Exchange | Neg Risk CTF Exchange |
| Multi-outcome | Independent markets | Linked via conversion |
| `negRisk` flag | `false` | `true` |
| Order option | `negRisk: false` | `negRisk: true` |
## Negative Risk
Multi-outcome events where only one outcome can win. A No token in any market can be **converted** into 1 Yes token in every other market.
### Conversion Example
Event: "Who wins?" with outcomes Trump, Harris, Other.
| Outcome | Before | After Conversion |
|---------|--------|------------------|
| Trump | — | 1 Yes |
| Harris | — | 1 Yes |
| Other | 1 No | — |
Conversion is atomic through the Neg Risk Adapter contract.
### Identifying Neg Risk Markets
```json
{
"negRisk": true // on event or market object from API
}
```
When placing orders: pass `negRisk: true` in options.
## Augmented Negative Risk
For events where new outcomes emerge after trading begins (e.g., new candidate enters race).
| Outcome Type | Description |
|--------------|-------------|
| Named outcomes | Known outcomes (e.g., "Trump", "Harris") |
| Placeholder outcomes | Reserved slots clarified later (e.g., "Person A") |
| Explicit Other | Catches any unnamed outcome |
### Identifying
```json
{
"enableNegRisk": true,
"negRiskAugmented": true
}
```
### Rules
- Only trade on **named outcomes** — ignore placeholders
- If correct outcome is not named at resolution, market resolves to "Other"
- "Other" definition changes as placeholders are clarified — avoid trading it directly
## Token ID Computation
Token IDs are computed onchain in three steps:
1. `getConditionId(oracle, questionId, outcomeSlotCount)` — oracle = UMA CTF Adapter, outcomeSlotCount = 2 for binary
2. `getCollectionId(parentCollectionId, conditionId, indexSet)` — parentCollectionId = bytes32(0), indexSet = 1 (Yes) or 2 (No)
3. `getPositionId(collateralToken, collectionId)` — combines USDC.e contract address on Polygon with collection
In practice, get token IDs from the Markets API `tokens` array. Manual computation only needed for direct contract interaction.