Skip to main content

Principles

Always simulate first (to catch reverts early), display oracle/guard errors clearly (many protocol reverts are intentional safety checks), and prefer SDK actions for consistency and ABI safety.

Pattern (simulate → send → wait)

The SDK provides simulate-first helpers. You simulate via publicClient, send via walletClient, then wait for confirmation.
const sim = await actions.prepareCoreBorrow({
  publicClient,
  coreAddress,
  account,
  amount,
});

const hash = await actions.sendTx({ walletClient, request: sim.request });
await publicClient.waitForTransactionReceipt({ hash });

Borrow flow checklist

A typical borrow flow is: ensure ERC1155 approval via setApprovalForAll(coreAddress, true), deposit collateral with prepareCoreDeposit, borrow with prepareCoreBorrow, repay later with prepareCoreRepay (note the 1-minute repay delay), then withdraw with prepareCoreWithdraw.

Borrow: deposit collateral

const sim = await actions.prepareCoreDeposit({
  publicClient,
  coreAddress,
  account,
  positionIds,
  amounts,
});

const hash = await actions.sendTx({ walletClient, request: sim.request });
await publicClient.waitForTransactionReceipt({ hash });
Notes: Deposits can revert if the oracle considers the position invalid, stale, manually invalidated, or inside the early-closure window.

Borrow: borrow

const sim = await actions.prepareCoreBorrow({
  publicClient,
  coreAddress,
  account,
  amount,
});

const hash = await actions.sendTx({ walletClient, request: sim.request });
await publicClient.waitForTransactionReceipt({ hash });
Notes: Borrow can revert if amount < MIN_BORROW or amount > maxBorrow. The pool must have enough available liquidity (reserve is excluded).

Borrow: repay

const sim = await actions.prepareCoreRepay({
  publicClient,
  coreAddress,
  account,
  amount,
});

const hash = await actions.sendTx({ walletClient, request: sim.request });
await publicClient.waitForTransactionReceipt({ hash });
Notes: Repay is blocked for 1 minute after the most recent borrow, and partial repays cannot leave remaining debt below MIN_BORROW.

Lend: ERC4626 deposit

const sim = await actions.preparePoolDeposit({
  publicClient,
  poolAddress,
  account,
  assets,
  receiver,
});

const hash = await actions.sendTx({ walletClient, request: sim.request });
await publicClient.waitForTransactionReceipt({ hash });
Notes: Pool deposits can be capped (depositCap).

Approvals (one-time)

For approvals, ERC1155 collateral uses setApprovalForAll(coreAddress, true). ERC20 (USDC/USDT) uses approve(coreAddress, amount) for repay and approve(poolAddress, amount) for lending.