Smart Contract Reference
Developer reference for PredMart smart contracts: addresses, ABI, functions, events, and integration patterns.
Contract Addresses
| Contract | Network | Chain ID | Address |
|---|---|---|---|
| PredMart Lending Pool (Proxy) | Polygon Mainnet | 137 | 0xD90D012990F0245cAD29823bDF0B4C9AF207d9ee |
| USDC.e | Polygon Mainnet | 137 | 0x2791Bca1f2de4661ED88A30C99A7a9449Aa84174 |
| CTF (ERC-1155) | Polygon Mainnet | 137 | 0x4D97DCd97eC945f40cF65F87097ACe5EA0476045 |
The lending pool uses a UUPS proxy — always interact with the proxy address.
Core Functions
ERC-4626 Vault (Lending)
deposit(uint256 assets, address receiver) → uint256 shares
Deposits USDC and mints pUSDC shares to receiver. Requires prior USDC approval.
| Parameter | Type | Description |
|---|---|---|
assets |
uint256 | Amount of USDC to deposit (6 decimals) |
receiver |
address | Address to receive the minted pUSDC shares |
| Returns | uint256 | Number of pUSDC shares minted |
mint(uint256 shares, address receiver) → uint256 assets
Mints exact pUSDC shares by depositing required USDC.
| Parameter | Type | Description |
|---|---|---|
shares |
uint256 | Number of pUSDC shares to mint |
receiver |
address | Address to receive the minted shares |
| Returns | uint256 | Amount of USDC deposited |
withdraw(uint256 assets, address receiver, address owner) → uint256 shares
Withdraws exact USDC by burning required pUSDC. Requires pool liquidity; if owner != caller, requires allowance.
| Parameter | Type | Description |
|---|---|---|
assets |
uint256 | Amount of USDC to withdraw |
receiver |
address | Address to receive the USDC |
owner |
address | Address whose pUSDC shares will be burned |
| Returns | uint256 | Number of pUSDC shares burned |
redeem(uint256 shares, address receiver, address owner) → uint256 assets
Burns exact pUSDC shares and sends corresponding USDC.
| Parameter | Type | Description |
|---|---|---|
shares |
uint256 | Number of pUSDC shares to burn |
receiver |
address | Address to receive the USDC |
owner |
address | Address whose shares will be burned |
| Returns | uint256 | Amount of USDC withdrawn |
View Functions
| Function | Returns | Description |
|---|---|---|
totalAssets() |
uint256 | Total USDC in the pool (available + borrowed) |
convertToShares(uint256 assets) |
uint256 | How many pUSDC shares for a given USDC amount |
convertToAssets(uint256 shares) |
uint256 | How much USDC for a given number of pUSDC shares |
maxDeposit(address) |
uint256 | Maximum depositable amount |
maxWithdraw(address owner) |
uint256 | Maximum withdrawable amount |
maxRedeem(address owner) |
uint256 | Maximum redeemable shares |
previewDeposit(uint256 assets) |
uint256 | Preview shares from deposit |
previewMint(uint256 shares) |
uint256 | Preview assets needed for mint |
previewWithdraw(uint256 assets) |
uint256 | Preview shares burned for withdrawal |
previewRedeem(uint256 shares) |
uint256 | Preview assets from redemption |
Collateral Management
depositCollateral(uint256 tokenId, uint256 amount)
Deposits Polymarket CTF shares as collateral. Requires prior CTF.setApprovalForAll().
| Parameter | Type | Description |
|---|---|---|
tokenId |
uint256 | Polymarket outcome token ID |
amount |
uint256 | Number of shares to deposit |
depositCollateralFrom(address from, uint256 tokenId, uint256 amount)
Deposits collateral from another address. Relayer-only.
Borrowing (Meta-Transaction Relay)
borrowViaRelay(BorrowIntent intent, bytes signature, PriceData priceData)
Executes a borrow using user's signed intent and oracle-signed price. Relayer-only.
BorrowIntent struct:
struct BorrowIntent {
address borrower;
uint256 tokenId;
uint256 amount;
uint256 nonce;
uint256 deadline;
}
PriceData struct:
struct PriceData {
uint256 chainId;
address pool;
uint256 tokenId;
uint256 price; // WAD scale (0 to 1e18)
uint256 timestamp;
uint256 maxBorrow; // USDC units
bytes signature;
}
withdrawViaRelay(WithdrawIntent intent, bytes signature, PriceData priceData)
Withdraws collateral; verifies health factor >= 1.0 if debt exists. Relayer-only.
WithdrawIntent struct:
struct WithdrawIntent {
address borrower;
address to; // Destination address for the withdrawn collateral
uint256 tokenId;
uint256 amount;
uint256 nonce;
uint256 deadline;
}
Repayment
repay(uint256 tokenId, uint256 amount)
Repays debt; caller transfers USDC to pool, borrow shares burned. Use type(uint256).max for full repayment.
| Parameter | Type | Description |
|---|---|---|
tokenId |
uint256 | Token ID of the position to repay |
amount |
uint256 | Amount of USDC to repay (use type(uint256).max for full repayment) |
Liquidation
liquidate(address borrower, uint256 tokenId, PriceData priceData)
Liquidates unhealthy position by seizing all collateral. Liquidator-only.
| Parameter | Type | Description |
|---|---|---|
borrower |
address | Address of the borrower being liquidated |
tokenId |
uint256 | Token ID of the position |
priceData |
PriceData | Oracle-signed price data |
Behavior: Seizes 100% collateral, sells on CLOB, repays debt, charges liquidator fee. Residual USDC stays in pool (borrower does not receive it — full-liquidation model like perpetual futures). If underwater, shortfall absorbed as bad debt.
Leveraged Trading (Meta-Transaction Relay)
leverageViaRelay(LeverageAuth auth, bytes signature, PriceData priceData)
Executes leverage: deposits collateral shares and books pool advance as debt. Relayer-only.
LeverageAuth struct:
struct LeverageAuth {
address borrower;
address allowedFrom; // The Safe address where USDC must be sent
uint256 tokenId;
uint256 maxBorrow; // Maximum USDC the user authorizes
uint256 nonce;
uint256 deadline;
}
The allowedFrom field pins USDC destination to the user's Safe — the contract refuses to send funds elsewhere.
Market Resolution (Extension Pattern)
Resolution functions live in PredmartPoolExtension and are called via delegatecall through fallback() — call the same proxy address.
resolveMarket(uint256 tokenId, ResolutionData resolutionData)
Registers market resolution. Callable by anyone.
ResolutionData struct:
struct ResolutionData {
uint256 chainId;
address pool;
uint256 tokenId;
bool won;
uint256 timestamp;
bytes signature;
}
redeemWonCollateral(uint256 tokenId, bytes32 conditionId, uint256 indexSet)
Redeems winning CTF shares for USDC. Callable by anyone.
settleRedemption(address borrower, uint256 tokenId)
Settles position after redemption — repays debt, sends surplus to borrower. Callable by anyone.
closeLostPosition(address borrower, uint256 tokenId)
Closes losing-token position; writes off debt as bad debt. Callable by anyone.
View Functions (Position Data)
| Function | Returns | Description |
|---|---|---|
getPosition(address, uint256) |
Position | Collateral amount, borrow shares, timestamp |
getDebt(address, uint256) |
uint256 | Current debt including accrued interest |
getHealthFactor(address, uint256, uint256 price) |
uint256 | Health factor at given price (WAD) |
getLTV(uint256 price) |
uint256 | LTV ratio at given price (WAD) |
getLiquidationThreshold(uint256 price) |
uint256 | Liquidation threshold at price (WAD) |
totalBorrowAssets() |
uint256 | Total outstanding borrows including interest |
totalBorrowShares() |
uint256 | Total borrow share tokens |
totalBorrowedPerToken(uint256) |
uint256 | Total borrowed against a specific token |
borrowNonce(address) |
uint256 | Current borrow nonce for an address |
withdrawNonce(address) |
uint256 | Current withdraw nonce for an address |
leverageNonce(address) |
uint256 | Current leverage nonce for an address |
marketResolved(uint256) |
bool | Whether a market has been resolved |
marketWon(uint256) |
bool | Whether a resolved market was won |
paused() |
bool | Whether the protocol is paused |
admin() |
address | Current admin address |
relayer() |
address | Current relayer address |
liquidator() |
address | Current liquidator address |
oracle() |
address | Current oracle address |
protocolFeePool() |
uint256 | Accumulated protocol fees from profit fees |
poolCapBps() |
uint256 | Current pool cap in basis points |
reserves() |
uint256 | Accumulated protocol reserves |
unsettledRedemptions(uint256) |
Redemption | Redemption tracking for won markets |
Redemption Struct
Stored in unsettledRedemptions[tokenId]; consumed by settleRedemption() to distribute USDC proportionally.
struct Redemption {
bool redeemed; // Whether CTF shares have been redeemed for USDC
uint256 totalShares; // Total CTF shares that were redeemed
uint256 usdcReceived; // Actual USDC received from the CTF contract
}
Events
Collateral & Borrowing Events
event CollateralDeposited(address indexed borrower, uint256 indexed tokenId, uint256 amount);
event CollateralWithdrawn(address indexed borrower, uint256 indexed tokenId, uint256 amount);
event Borrowed(address indexed borrower, uint256 indexed tokenId, uint256 amount);
event Repaid(address indexed borrower, uint256 indexed tokenId, uint256 amount);
Liquidation Events
event Liquidated(address indexed liquidator, address indexed borrower, uint256 indexed tokenId, uint256 collateralSeized, uint256 debtRepaid);
// LiquidationSettled: surplus stays in pool, not sent to borrower
event LiquidationSettled(address indexed borrower, uint256 indexed tokenId, uint256 debtRepaid, uint256 liquidatorFee, uint256 surplus);
event BadDebtAbsorbed(address indexed borrower, uint256 indexed tokenId, uint256 amount);
event ProfitFeeCollected(address indexed borrower, uint256 indexed tokenId, uint256 feeAmount, uint256 toPool, uint256 toProtocol);
Market Resolution Events
event MarketResolvedEvent(uint256 indexed tokenId, bool won);
event PositionClosed(address indexed borrower, uint256 indexed tokenId, uint256 badDebt);
event CollateralRedeemed(uint256 indexed tokenId, uint256 sharesRedeemed, uint256 usdcReceived);
event RedemptionSettled(address indexed borrower, uint256 indexed tokenId, uint256 debtRepaid, uint256 surplusToUser);
Interest & Reserves Events
event InterestAccrued(uint256 interest, uint256 reserve);
event ReservesWithdrawn(address indexed to, uint256 amount);
Admin Events
event OracleUpdated(address indexed oldOracle, address indexed newOracle);
event AnchorsUpdated();
event PausedStateChanged(bool paused);
event TimelockActivated(uint256 delay);
event PoolCapUpdated(uint256 newCapBps);
event RelayerUpdated(address indexed oldRelayer, address indexed newRelayer);
Governance (Timelock) Events
event OracleChangeProposed(address indexed newOracle, uint256 executeAfter);
event OracleChangeCancelled();
event AnchorsChangeProposed(uint256 executeAfter);
event AnchorsChangeCancelled();
event UpgradeProposed(address indexed newImplementation, uint256 executeAfter);
event UpgradeCancelled();
ERC-4626 Vault Events
Standard ERC-4626/ERC-20 events: Deposit, Withdraw, Transfer, Approval.
EIP-712 Domain
EIP-712 typed data for signing intents:
EIP712Domain({
name: "Predmart Lending Pool",
version: "1.0.0",
chainId: 137, // Polygon Mainnet
verifyingContract: 0xD90D012990F0245cAD29823bDF0B4C9AF207d9ee
})
BorrowIntent Type Hash
BorrowIntent(address borrower,uint256 tokenId,uint256 amount,uint256 nonce,uint256 deadline)
WithdrawIntent Type Hash
WithdrawIntent(address borrower,address to,uint256 tokenId,uint256 amount,uint256 nonce,uint256 deadline)
LeverageAuth Type Hash
LeverageAuth(address borrower,address allowedFrom,uint256 tokenId,uint256 maxBorrow,uint256 nonce,uint256 deadline)
The allowedFrom field pins USDC destination to the user's Safe.
Nonce Separation
Separate nonces per operation type prevent cross-operation replay:
- borrowNonce(address) — borrow operations
- withdrawNonce(address) — withdrawal operations
- leverageNonce(address) — leverage operations
REST API Endpoints
REST API at https://api.predmart.com. Full docs: api.predmart.com/docs.
Key Endpoints
| Endpoint | Method | Description |
|---|---|---|
/lending/pool-stats |
GET | Pool TVL, utilization, rates |
/lending/position/{address}/{token_id} |
GET | Single position with risk metrics |
/lending/positions/{address} |
GET | All positions for a wallet |
/lending/events/{address} |
GET | Lending event history |
/lending/liquidations/{address} |
GET | Liquidation history |
/lending/rate-history |
GET | Historical rate data |
/lending/depth-status |
GET | Per-market borrow cap status per token |
/lending/constants |
GET | Contract addresses and protocol params |
/oracle/borrow-intent/{borrower}/{token_id}/{amount} |
GET | EIP-712 data for borrow signing |
/oracle/borrow-relay |
POST | Submit signed borrow intent |
/oracle/withdraw-intent/{borrower}/{to}/{token_id}/{amount} |
GET | EIP-712 data for withdraw signing |
/oracle/withdraw-relay |
POST | Submit signed withdraw intent |
Integration Example: Reading a Position
import { Contract, JsonRpcProvider, parseUnits, formatUnits } from 'ethers';
const POOL = '0xD90D012990F0245cAD29823bDF0B4C9AF207d9ee';
const pool = new Contract(POOL, [
'function getPosition(address,uint256) view returns (uint256,uint256,uint256)',
'function getDebt(address,uint256) view returns (uint256)',
'function getHealthFactor(address,uint256,uint256) view returns (uint256)',
], new JsonRpcProvider('https://polygon-rpc.com'));
const [collateral] = await pool.getPosition(borrower, tokenId);
const debt = await pool.getDebt(borrower, tokenId);
const hf = await pool.getHealthFactor(borrower, tokenId, parseUnits('0.65', 18));
console.log({ collateral, debt: formatUnits(debt, 6), hf: formatUnits(hf, 18) });
Deployment Details
| Property | Value |
|---|---|
| Solidity Pragma | ^0.8.24 |
| Compiler Version | 0.8.27 |
| Protocol Version | 1.0.0 |
| Optimizer | Enabled, 1 run |
| via_ir | Enabled |
| Proxy Pattern | UUPS (ERC-1967) |
| Framework | Foundry |
| Network | Polygon (EVM-compatible) |
Next Steps
- Protocol Constants — All parameter values in one place
- Security — Trust assumptions and security model
- FAQ — Common developer questions