Skip to main content
If you’re integrating headless (your own UI calling the engine directly), this page is the on-chain surface you’ll need. Embed integrations don’t need this page — the iframe handles everything.

BarkerEngine is ERC-4626

BarkerEngine is a standard ERC-4626 vault. If your stack already has ERC-4626 helpers (Wagmi / viem / OpenZeppelin SDK), they work out of the box — engine.balanceOf(user) returns shares, engine.convertToAssets(shares) returns asset value. The engine address is per-partner, returned by GET /api/partner/products as engine_contract_address. There is no static “Barker engine per chain” — every partner has their own.

Functions you’ll call

// Deposit `assets`, mint shares to `receiver`. Returns shares minted.
function deposit(uint256 assets, address receiver) external returns (uint256 shares);

// Burn `shares` from `owner`, send assets to `receiver`.
// owner ≠ caller requires ERC-20 allowance.
function redeem(uint256 shares, address receiver, address owner) external returns (uint256 assets);

// Burn enough shares from `owner` to send exactly `assets` to `receiver`.
function withdraw(uint256 assets, address receiver, address owner) external returns (uint256 shares);

// Show "you'll receive" copy before signing
function previewDeposit(uint256 assets) external view returns (uint256 shares);
function previewRedeem(uint256 shares) external view returns (uint256 assets);

// User's position (in shares + asset-denominated value)
function balanceOf(address user) external view returns (uint256 shares);
function convertToAssets(uint256 shares) external view returns (uint256 assets);

// Underlying asset (e.g. USDC) the engine wraps
function asset() external view returns (address);

Minimal ABI fragment (copy-paste)

[
  { "type":"function","name":"deposit","stateMutability":"nonpayable","inputs":[{"name":"assets","type":"uint256"},{"name":"receiver","type":"address"}],"outputs":[{"type":"uint256"}] },
  { "type":"function","name":"redeem","stateMutability":"nonpayable","inputs":[{"name":"shares","type":"uint256"},{"name":"receiver","type":"address"},{"name":"owner","type":"address"}],"outputs":[{"type":"uint256"}] },
  { "type":"function","name":"withdraw","stateMutability":"nonpayable","inputs":[{"name":"assets","type":"uint256"},{"name":"receiver","type":"address"},{"name":"owner","type":"address"}],"outputs":[{"type":"uint256"}] },
  { "type":"function","name":"balanceOf","stateMutability":"view","inputs":[{"name":"account","type":"address"}],"outputs":[{"type":"uint256"}] },
  { "type":"function","name":"convertToAssets","stateMutability":"view","inputs":[{"name":"shares","type":"uint256"}],"outputs":[{"type":"uint256"}] },
  { "type":"function","name":"previewDeposit","stateMutability":"view","inputs":[{"name":"assets","type":"uint256"}],"outputs":[{"type":"uint256"}] },
  { "type":"function","name":"previewRedeem","stateMutability":"view","inputs":[{"name":"shares","type":"uint256"}],"outputs":[{"type":"uint256"}] },
  { "type":"function","name":"asset","stateMutability":"view","inputs":[],"outputs":[{"type":"address"}] }
]
For the full ABI, pull the verified contract from the chain explorer using engine_contract_address.

Permit (optional, saves one tx)

If the underlying token (USDC, USDT, DAI…) supports EIP-2612 permit, you can swap the approve transaction for a signed message — one tx instead of two.
const signature = await wallet.signTypedData({
  domain: { name: "USD Coin", version: "2", chainId, verifyingContract: usdcAddr },
  types: {
    Permit: [
      { name: "owner", type: "address" },
      { name: "spender", type: "address" },
      { name: "value", type: "uint256" },
      { name: "nonce", type: "uint256" },
      { name: "deadline", type: "uint256" },
    ],
  },
  primaryType: "Permit",
  message: { owner: user, spender: engineAddr, value: amount, nonce, deadline },
});
// then submit one tx that calls permit() + deposit() atomically
// (use a multicall helper from your wallet stack)
BarkerEngine doesn’t bundle permit + deposit in one function. Use multicall (Wagmi/viem) or a thin partner-owned router contract.

Safety properties

  • Non-upgradeable per deployment — once deployed, bytecode never changes.
  • No admin withdrawal path — funds can only exit via the user’s redeem / withdraw.

What’s next