Skip to main content

Session policy

SessionPolicyContract restricts the authorization contexts accepted by a smart-account session rule. Its constructor fixes the forwarder, markets, token, and fee recipient. The smart account authenticates the signers and chooses a context rule. The policy then checks each context passed to enforce.

Constructor​

fn __constructor(
e: Env,
forwarder: Address,
markets: Vec<Address>,
token: Address,
fee_recipient: Address,
)
ArgumentMeaning
forwarderContract allowed to collect the relay fee.
marketsContracts accepted as market contexts and token-transfer destinations.
tokenToken accepted for transfers and approvals.
fee_recipientRequired signed recipient on a forwarder context.

The constructor writes four instance values. It performs no address, uniqueness, or nonempty-list validation. The contract exports no configuration setter.

Policy interface​

Policy::AccountParams is (). The installation value carries no account-specific configuration.

fn enforce(
e: &Env,
context: Context,
authenticated_signers: Vec<Signer>,
_context_rule: ContextRule,
smart_account: Address,
)

fn install(
_e: &Env,
_params: Self::AccountParams,
_context_rule: ContextRule,
smart_account: Address,
)

fn uninstall(
_e: &Env,
_context_rule: ContextRule,
smart_account: Address,
)

All three entries call smart_account.require_auth. They return void. install and uninstall make no policy storage writes.

enforce argumentMeaning
contextOne authorization context from the smart account.
authenticated_signersSigners already authenticated by the smart account. The policy needs at least one.
_context_ruleThe enclosing rule. The policy accepts it but reads no fields.
smart_accountAccount that must authorize the policy call.

The policy checks a nonempty signer vector. It does not compare signer identities itself. The smart account's rule defines which signers qualify.

Accepted contexts​

enforce accepts only Context::Contract. Branches run in this order:

ContextCheck
Configured forwarderArgument 3 decodes as the configured fee_recipient.
Configured token, transferArgument 1 decodes as an address in markets.
Configured token, approveArgument 1 decodes as forwarder.
Address in marketsAccepted for any function and arguments.
Any remaining contextRejected.

The forwarder context contains its signed arguments. Position 3 is the fee recipient for both forward and forward_dynamic. The forwarder branch checks that recipient. It does not check its function name, fee amount, fee token, or target fields.

Each nested action that authenticates the smart account becomes another context. A token approval is therefore checked separately from the forwarder root.

The token branch checks the function and destination. It leaves the amount and approval deadline to the token and the surrounding authorization. A transfer destination that fails address decoding raises TransferNotAllowed. This includes a muxed destination. An undecodable approval spender raises ApproveNotAllowed.

For the forwarder's signed argument layout, read the fee-forwarder reference.

Contract scope is not a spending limit

The policy accepts any amount in an allowed market transfer or forwarder approval. It accepts any authorized function on an allowed market. The constructor's bindings restrict destinations. They do not impose a balance cap, an order-size cap, or a per-session spending budget.

Rule expiration and removal​

The policy ignores _context_rule, including valid_until. The smart account enforces the rule's ledger expiration before policy execution. Removing that rule from the smart account removes the delegation. A browser's local session state does not change the on-chain rule. The one-click trading guide explains the user controls and revocation flow.

Errors​

CodeVariantCondition
4002ContractNotAllowedA non-contract context or an unrecognized contract.
4003FunctionNotAllowedThe token function is neither transfer nor approve.
4004TransferNotAllowedThe token transfer destination is not a configured market.
4005ApproveNotAllowedThe token approval spender is not the configured forwarder.
4006ForwardNotAllowedThe signed forwarder recipient does not decode as the configured recipient.
4007SignerNotAuthenticatedauthenticated_signers is empty.

The smart-account authorization check runs first. Host authorization errors therefore precede these policy checks. Within enforce, the empty-signer check runs before context validation. Constructor and lifecycle calls declare no additional contract errors.

Storage and events​

Instance keyTypeWritten by
forwarderAddressConstructor
marketsVec<Address>Constructor
tokenAddressConstructor
recipientAddressConstructor

After the signer check, enforce calls extend_ttl with TTL_THRESHOLD and EXTEND_AMOUNT. Their values are 501120 and 518400 ledgers. At 17280 ledgers per day, the extension target is approximately 30 days. A failed invocation rolls back the extension.

The policy emits no events. The smart account owns the rule lifecycle and its receipts. Current bindings appear in Deployments.