All pages

Using Trimmy

Fees, limits and security

The exact allowance, the keeper fee, the 50-bip oracle floor, the 64-second feed age, and what the contract can never do to you.

Working with an agent? Every page here has a markdown twin, the whole site is one file at llms-full.txt, and trimmy-mcp lets it read live rules and compose a payment it cannot send.

Testnet. Trimmy runs on Flare Coston2. Nothing described here has run on Flare mainnet, and no page on this site describes real money.

An XRPL arming payment cannot be recalled. This is what a rule can take from you, and what nothing here can take.

The allowance is exact

The arming batch is two calls, approve then arm. The approve is sized to the rule's whole life, to the unit.

allowance = totalSellAmount + keeperFeeBudget

The rule that ran end to end on Coston2 sold 1,000,000 UBA of FXRP with a 9,400 UBA keeper budget, so its allowance read back on chain as 1,009,400. Not unlimited, and there is no second approval in the flow. An allowance belongs to the pair (your account, the Trimmy contract), not to a rule, so cancelling leaves it standing: Managing and cancelling rules covers clearing it.

The keeper fee

execute is permissionless and pays its caller a flat fee out of the proceeds, so the rule funds its own execution and nobody has to be watching it.

The fee has to beat gas. Measured: execute() costs 383,451 gas, which at Coston2's 2125 gwei and an FLR/USD of 0.00594005 is $0.00484, or 4,698 UBA of FXRP. Live rules carry a keeperFeeFlat of 9,400 UBA, about twice that. Coston2's gas price is a testnet artefact, not Flare's mainnet market. A PRIVATE execution costs more: 517,962 gas measured.

keeperFeeBudget is a lifetime cap, never exceeded and never paid beyond the proceeds. arm refuses a budget too small to fund the rule's executions, because a rule that runs out of fee stops with months left and a live allowance. A protocol fee follows, capped at 50 bips. Live rules carry 0.

The floor: two legs, 50 bips

slippageBips is capped at 50 (0.5%) by a constant in a contract with no admin. The floor comes from FTSO, never from the venue: oracleOut × (10,000 − slippageBips) / 10,000, or minOutAbsolute when higher. An AMM quote is a number an attacker can move, so it never sets the floor.

The price behind it is two-legged, sell feed against buy feed. A single-leg read against USD is correct only if the buy token is worth exactly $1, on a chain carrying at least five unrelated tokens called "USDC". A threshold is therefore in buy-token base units per one whole sell token.

The floor is on the gross fill, so fees come out afterwards and what lands is lower by that much; a net-bound floor is unsatisfiable, since a flat keeper fee is often a larger share of a small part than the 50-bip band. It also latches on the first execution so later parts do not chase the market down, decaying back to live over one hour.

A thin or stale venue gives a refusal, not a bad fill: on our pool a 0.05 FXRP sell was refused three times while the pool sat below the oracle, by 36.6 bips when measured, then filled at 5.6 bips once repriced.

maxFeedAge is 64 seconds, measured

Read live from the contract: 64. Feed age is block.timestamp − feedTimestamp as the contract sees it, sampled over five separated windows and 750 samples: largest per-window p99 34 seconds, global maximum 35 seconds. 64 is roughly twice that.

An earlier deployment carried 120 seconds, chosen before that sampling. A five-minute realised XRP move already exceeds the whole 50-bip band, so every extra second of staleness is extractable. The cost, stated plainly: maxFeedAge is immutable and there is no proxy, so an FTSO stall longer than 64 seconds halts every rule until feeds recover.

No owner, no admin, no proxy

No pause, no rescue. The token and venue allowlists are written once in the constructor: 2 tokens (FXRP, WC2FLR) and 2 venues (a V3 router at the 3000 fee tier, a queued vault). Proceeds have one destination, rule.account.

A mandate software can compose but cannot exceed

Every agentic wallet bounds what an agent may do. What differs is who enforces the bound.

agentic wallet Trimmy rule
enforced by the vendor a contract with no admin
spend a policy an exact allowance: sell amount plus keeper budget
scope configurable one verb, one venue, one pair, fixed at arm time
stop ask the vendor cancel, or one epoch bump for every rule

PersonalAccount.executeUserOp carries onlyController, measured, so an agent holding a keeper key cannot drive your account and its allowance to Trimmy is zero: a compromised agent extracts zero. With a PRIVATE rule it never learns your threshold, which lives in the enclave behind an on-chain commitment.

This is not wallet-lessness, which Smart Accounts and Axelar GMP already give you. What a rule adds is persistence.

What is not safe yet

Source on GitHub Read this page as markdown: /docs/fees-limits-security/index.md