# `gno.land/r/moul/x/grc20wrapdemo/v0` **A permissionless wrapper factory for GRC20 tokens.** Point it at any token registered in [`r/nt/grc20reg`](https://gno.land/r/nt/grc20reg/v0) and it issues a new one backed by it, with a personality you pick. Point it at two and it issues a meta-token backed by both. No allowlist, no owner, and no authority over anybody's balance: every deposit is pulled with an allowance the holder granted. ## Five minutes, start to finish ``` # 1. play money maketx call -pkgpath gno.land/r/moul/x/grc20faucet/v0 -func Claim # 2. let this realm pull your RED (the address is printed by Home(), and on the # realm's own page) maketx call -pkgpath gno.land/r/moul/x/grc20faucet/v0 -func Approve \ -args RED -args -args 1000000 # 3. create a wrapper over RED, and deposit into it maketx call -pkgpath gno.land/r/moul/x/grc20wrapdemo/v0 -func NewWrapper \ -args gno.land/r/moul/x/grc20faucet/v0.RED -args pool -args pRED maketx call -pkgpath gno.land/r/moul/x/grc20wrapdemo/v0 -func Deposit \ -args pRED -args 500000 ``` Step 2 is the one people skip. Without it every `Deposit` fails with `insufficient allowance`, which is the system working. ## Modes | mode | what the wrapped token does | |---|---| | `plain` | 1:1 custody receipt | | `kilo` | 1 underlying unit becomes 1000 wrapped, +3 decimals | | `soulbound` | wrap and unwrap freely, never transferable | | `pool` | shares in the escrow; `Donate` pays every holder at once | | `sticky` | `pool` plus a 1% exit fee, left behind for whoever stays | And `NewFusion(keyA, perA, keyB, perB, symbol)`, which bundles two registered tokens at a fixed proportion into one meta-token, `Fuse` in and `Defuse` out. ## The parts worth reading the code for **`pool` is the entire yield-bearing-token pattern in two lines of arithmetic.** `Donate` adds escrow and mints nothing, so every outstanding share is worth more, permanently and for everyone at once. A fee sink, a staking reward and an airdrop to holders are the same operation seen from three angles. **`soulbound` binds users, not realms.** `MsgCall` cannot build the `realm` argument grc20's tellers need, so a signing account can only move the token through this realm's `Transfer`, where the veto lives. Another realm holding it can always move its own balance. Non-transferable here means "no user can pass it on", and the exit is always open: unwrap, and the underlying moves freely again. **Wrapping a wrapper works, and nothing special was needed to make it work.** Every token this realm issues is itself registered in `grc20reg`, so its key feeds straight back into `NewWrapper`. A pool over a plain wrap of RED is a good way to see how thin the abstraction is. **Two wrappers over the same underlying share one escrow account** (this realm's address), and are kept apart only by each vault's own `Held()` counter. `Escrow` reports that counter; the render page reports whether the account still covers it. Built on [`p/moul/x/grc20wrap`](https://github.com/moul/gno-contracts/tree/main/p/moul/x/grc20wrap/v0), which is where the wrapping actually happens. This realm is the chain wiring and a catalogue. --- Part of **[moul/gno-contracts](https://github.com/moul/gno-contracts)** โ€” moul's versioned gno.land contracts. See the repository for the full catalog, build/test tooling, and usage. **Dependency graph:** ![gno.land/r/moul/x/grc20wrapdemo/v0 dependency graph](https://raw.githubusercontent.com/moul/gno-contracts/main/_assets/gno.land/r/moul/x/grc20wrapdemo/v0/deps.png) > ๐Ÿงช **Highly experimental โ€” potentially vibe-coded.** Not audited; may break, change, or be removed at any time. Do not use with anything of value. Full disclaimer: [DISCLAIMER](https://github.com/moul/gno-contracts/blob/main/DISCLAIMER.md).