Skip to content

Contracts without "onBehalfOf"

Overview

This guide demonstrates how to handle contracts that do not support the onBehalfOf pattern. And instead, credit positions directly to msg.sender.

The solutions presented here only apply to contracts that credit tokenized, transferrable positions.

1:1 Deposits

For tokenized positions that mint 1:1 with deposit amount, you can use a simple multi-call order (an order with multiple successive calls).

1:1 ERC20 Deposits

This example shows how to deposit ERC20 tokens into a vault that mint 1:1 with the deposit amount. The order of operations is

  1. Deposit into the vault
  2. Transfer the vault tokens to the user

The address that receives vault tokens post-deposit is the SolverNetExecutor - the contract that executes order calls.

const depositToken = '0x...' as const;  // The token to deposit
const depositAmount = parseEther('1');  // Amount to deposit into the vault
const vault = "0x..." as const;         // Your tokenized vault address
const vaultToken = "0x..." as const;    // The ERC20 token minted by the vault to msg.sender
const user  = "0x..." as const;         // The final recipient of the vault tokens
 
const order = useOrder({
    // ...
    calls: [
        // 1. Deposit into the vault
        {
            target: vault,
            abi: vaultABI, // ABI for Vault.deposit(amount)
            functionName: 'deposit',
            args: [depositAmount],
        },
        // 2. Transfer the vault tokens to the user
        {
            target: vaultToken,
            abi: erc20ABI,
            functionName: 'transfer',
            args: [userAddress, depositAmount],
        },
    ],
    expense: {
        token: depositToken,
        amount: depositAmount,
        spender: vault,
    },
})

1:1 Native Deposits

This example shows how to deposit native tokens into a vault that mint 1:1 with the deposit amount. It follows the same pattern as the ERC20 example, with some minor differences (highlighted in comments).

const depositAmount = parseEther('1');  // Amount to deposit into the vault
const vault = "0x..." as const;         // Your tokenized vault address
const vaultToken = "0x..." as const;    // The ERC20 token minted by the vault to msg.sender
const user  = "0x..." as const;         // The final recipient of the vault tokens
 
const order = useOrder({
    // ...
    calls: [
        // 1. Deposit into the vault
        {
            target: vault,
            abi: vaultABI, // ABI for Vault.deposit{ value: amount }()
            functionName: 'deposit',
            value: depositAmount, // ** Send native value to the vault
        },
        // 2. Transfer the vault tokens to the user
        {
            target: vaultToken,
            abi: erc20ABI,
            functionName: 'transfer',
            args: [userAddress, depositAmount],
        },
    ],
    expense: {
        token: depositToken,
        amount: depositAmount,
        // ** No spender needed for native token expense
    },
})

Variable Mint

"Variable mints" refer to vaults that mint an unkown (variable) amount of vault tokens.

For tokenized positions with uknown, variable mint amounts, you can use the withExecAndTransfer utility.