supply and Morpho vaultBundlesV1Deposit calls used by Para’s yield builders with complete policy JSON.
The same rules apply when the signing request comes through REST or an SDK. They compare the value declared in the call, not a simulated or executed balance change, and do not add a daily spending budget.
Choose the fact and units
request.uintArgs[n] exposes a decoded top-level uint8 through uint256 argument, indexed from zero. Its value is a decimal digit string; use eq, ne, lt, lte, gt or gte. Para compares the integers without converting token decimals, shares or prices.
For a six-decimal USDC amount, "100000000" means 100 USDC. A numeric argument may instead represent shares, a deadline, an identifier or a price bound: confirm the function’s meaning before treating it as money.
Signed integers, numeric strings, bytes, array elements and tuple members do not expose
request.uintArgs[n]. A top-level unsigned argument can still be read when another argument is a tuple. Existing request.args[n] stays a string fact with eq, ne and in.
Para classifies the three-argument ERC-721 safeTransferFrom as transfer_nfts. Plain ERC-721 transferFrom(address,address,uint256) shares its selector with ERC-20 transferFrom and is currently classified as transfer_tokens; its request.uintArgs[2] still represents a token ID. Bind the exact contract and function instead of assuming the action classification makes an argument a fungible amount.
On a decoded Safe execTransaction, request.uintArgs[n] describes the outer function’s arguments, not inferred spending inside its calldata. Use the existing request.safe.* facts for a readable inner payment; the unsigned argument facts do not traverse nested calls.
Bind the whole call
Useselector.chainId, request.target and request.abi.selector together. The selector identifies the exact function signature, including argument types, rather than just its name. Then bind the asset or trusted asset-specific vault, beneficiary where the call takes one, and any native value attached to the call.
Values for request.abi.selector must be 0x followed by exactly eight hex characters. Selector comparisons ignore hex letter case; malformed values fail policy validation.
The Guardrails below target an exact contract and function, then deny not(all expected deposit conditions). Both policies can apply to the same wallet.
See Facts Para cannot read for which failures qualify for decode-gap fallback.
Aave: limit decoded supply calls to 100 USDC
For decoded Aave V3supply calls to the configured Base pool, this policy requires native USDC, no attached ETH and the signing wallet as beneficiary. The function selector is 0x617ba037; argument 1 is the amount, argument 0 the asset and argument 2 the beneficiary.
Replace YOUR_WALLET_ID with the wallet’s Para ID and 0x1111111111111111111111111111111111111111 with that same wallet’s address. The deposit cap applies whether the flow first needs an approval or reuses an existing allowance. Configure approval controls separately with the existing token facts.
aave-deposit-limit.json
Morpho: limit decoded vaultBundlesV1Deposit calls to 100 USDC
For decodedvaultBundlesV1Deposit(address,uint256,uint256,(uint8,bytes),uint256,address,uint256) calls to the official Base wrapper, this policy requires the supported Steakhouse Prime V2 USDC vault. The selector is 0x6bbba4e0; argument 1 is the gross asset amount, not the share-price bound in argument 2. The zero referral-fee condition keeps that gross amount equal to the assets deposited.
The official wrapper deposits shares for its caller, so there is no beneficiary argument. The wallet ID scopes this direct call to the signing wallet. USDC is bound through the fixed supported vault, whose underlying asset is USDC, rather than through request.token.asset, which is unavailable on generic contract calls.
Replace YOUR_WALLET_ID with the wallet’s Para ID. Approvals target the wrapper, not the vault; fixed withdrawals and full redemptions target the vault instead and retain their existing policy behavior.
morpho-deposit-limit.json