Skip to content Search Apps Documentation Source Content File Folder Download Copy Actions State String Boolean Number Struct Map Slice Pointer Function Closure Reference Nil Package Type Interface Unknown

Community realm. Read the code first. Community realm, deployed by its author. Read the code before you interact or send coins.

/r/g1magld5ptgzaktqcexxq0pgq5lmdf0kz6re8hlv/demo/vault/v0

Directory · 4 Files
README.md Open

gno.land/r/moul/demo/vault

Step 7 and last of the r/moul/demo walkthrough: a time-locked vault over the GRC20 token from grc20.

Withdrawing is deliberately two steps, so that a stolen key does not drain the vault in one transaction:

1func Deposit(cur realm, amount uint, recoverAddress address)  // caller -> vault
2func Unvault(cur realm, amount uint)                          // arm the timer
3func Redeem(cur realm, amount uint)                           // after the lock
4func Recover(cur realm, target address)                       // escape hatch

Unvault moves an amount from vaulted to pending and stamps unlockAt = ChainHeight() + 100. Redeem refuses until the chain passes that height. In between, the depositor (or whoever is watching) can call Recover to push the still-locked balance to the recovery address recorded at deposit time. That is the pattern: a withdrawal announces itself, and the announcement window is when a theft can be reversed.

Deposited tokens live at the realm's own address (cur.Address()), which is what makes the vault custodial rather than an accounting fiction.

What is wrong with it on purpose

This is a demo, and two things would sink it in production:

  • Recover has no caller check. Anyone can call Recover(target) for any target. It only ever pays out to the address the target itself recorded, so it cannot steal, but it is a free denial of service: a bystander can rewind anyone's deposit at will.
  • Only Unvault/Redeem are covered by tests. Recover has none, flagged as a TODO in the test file.

Read it for the two-step withdrawal shape, not as a vault to deploy. (Note that r/moul/x/daily/vault is a different thing entirely: a key-value store, not a token vault.)

Previous: grc20.


Part of moul/gno-contracts — moul's versioned gno.land contracts. See the repository for the full catalog, build/test tooling, and usage.

On mainnet: deployment status transactions unique callers deployed revision

Dependency graph:

gno.land/r/moul/demo/vault/v0 dependency graph

⚠️ Disclaimer: provided as-is, without warranty; not security-audited. Full disclaimer: DISCLAIMER.