Skip to main content

Holdings

Internal token ledger used by the protocol. Users can deposit tokens, move balances internally, withdraw to external wallets, approve allowlisted operators such as Settlement, and authorize third-party submission through signatures.

Deposits

Direct deposit

function deposit(address to, address token, uint256 amount)
Pulls tokens from msg.sender into Holdings and credits the internal balance of to.

Deposit with Permit2

function depositWithPermit(
    address from,
    address to,
    address token,
    uint256 amount,
    uint256 nonce,
    uint256 deadline,
    bytes calldata signature
);
Permit2-powered deposit. Pulls tokens from from and credits the Holdings balance of to. Anyone can submit the transaction if they have the Permit2 signature.

Batch deposits

function batchDeposit(address to, address[] calldata tokens, uint256[] calldata amounts)
function batchDepositWithPermit(
    address from,
    address to,
    address[] calldata tokens,
    uint256[] calldata amounts,
    uint256[] calldata nonces,
    uint256[] calldata deadlines,
    bytes[] calldata signatures
);
function batchDepositMultipleRecipients(Deposit[] calldata deposits);

struct Deposit {
    address to;
    address token;
    uint256 amount;
}
Batch variants for depositing one sender’s external tokens into one or many Holdings balances.

Withdrawals

Direct withdrawal

function withdraw(address to, address token, uint256 amount);
function batchWithdraw(address to, address[] calldata tokens, uint256[] calldata amounts);
Withdraws from the caller’s Holdings balance to an arbitrary external recipient to.

Withdrawal by signature

function withdrawBySig(
    address from,
    address to,
    address token,
    uint256 amount,
    uint256 nonce,
    uint256 deadline,
    bytes calldata signature
);

function batchWithdrawBySig(
    address from,
    address to,
    address[] calldata tokens,
    uint256[] calldata amounts,
    uint256 nonce,
    uint256 deadline,
    bytes calldata signature
);
Relayer-callable withdraw flows authorized by EIP-712 signatures from from.

Transfers

Direct transfer

function transfer(address to, address token, uint256 amount);
function batchTransfer(address[] calldata recipients, address[] calldata tokens, uint256[] calldata amounts);
Moves balances entirely inside Holdings without touching external wallets.

Transfer by signature

function transferBySig(
    address from,
    address to,
    address token,
    uint256 amount,
    uint256 nonce,
    uint256 deadline,
    bytes calldata signature
);

function batchTransferBySig(
    address from,
    address[] calldata recipients,
    address[] calldata tokens,
    uint256[] calldata amounts,
    uint256 nonce,
    uint256 deadline,
    bytes calldata signature
);
Relayer-callable internal transfer flows authorized by EIP-712 signatures from from.

Operator management

function setOperator(address operator, bool approved);
function setOperatorBySig(
    address user,
    address operator,
    bool approved,
    uint256 nonce,
    uint256 deadline,
    bytes calldata signature
);
Approves or revokes an allowlisted operator for the user’s Holdings balances. Settlement relies on this operator model for Holdings-native trading and lifecycle actions.

Operator actions

function transferFrom(address from, address to, address token, uint256 amount);
function batchTransferFrom(Transfer[] calldata transfers);
function withdrawFrom(address from, address token, uint256 amount);
function batchWithdrawFrom(Withdraw[] calldata withdrawals);

struct Transfer {
    address from;
    address to;
    address token;
    uint256 amount;
}

struct Withdraw {
    address from;
    address token;
    uint256 amount;
}
Allowlisted operators can move or withdraw balances for users that have approved them.

Events

event OperatorSet(address indexed user, address indexed operator, bool approved);
event Deposited(address indexed from, address indexed to, address indexed token, uint256 amount);
event Withdrawn(address indexed from, address indexed to, address indexed token, uint256 amount);
event BalanceUpdated(address indexed user, address indexed token, uint256 newBalance);
Deposited and Withdrawn are also emitted for internal Holdings transfers, so integrations should treat them as ledger movement events, not only external wallet ingress/egress.