Transaction
B43FAC7190CF64…D7E74E202E02
Block 26,343 · index 0 · indexed
Summary
- Hash
- B43FAC7190CF64B00B90B718FD16F92333B47B6322514FF9B473D7E74E202E02
- Block
- 26,343
- Size
- 4275 bytes
- Gas used
- 9,734,905 / 11,681,946
- Fee
- 1000000ugnot
- Memo
- gnopublish
- Status
- success
Messages
Arguments · 9
- #1vault
- #2README.md
- #3# `gno.land/r/moul/demo/vault/v0` _TODO: describe this package._ <!-- BEGIN GNOCONTRACTS FOOTER (generated by `make readmes`; do not edit below) --> --- 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:**  > ⚠️ **Disclaimer:** provided as-is, without warranty; not security-audited. Full disclaimer: [DISCLAIMER](https://github.com/moul/gno-contracts/blob/main/DISCLAIMER.md). <!-- END GNOCONTRACTS FOOTER -->
- #4contract.gno
- #5// Package vault demonstrates a minimal time-locked token vault built on top of // the grc20 token package. Deposited tokens are held at the realm's own // address; withdrawing them is a two-step process: Unvault marks an amount for // withdrawal and starts a lock timer, then (once the lock elapses) Redeem moves // the tokens back to the depositor. package vault import ( "chain/runtime" "chain/runtime/unsafe" tokens "gno.land/p/nt/grc20/v0" ) // test1 receives the initial mint at construction. var test1 = address("g1jg8mtutu9khhfwc4nxmuhcpftf0pajdhfvsqf5") // lockDuration is the number of blocks that must pass between Unvault and // Redeem. const lockDuration = int64(100) // Token and FooVault-equivalent state are exported for reading; privateLedger // stays unexported (unrestricted mint/burn/transfer). var ( Token *tokens.Token privateLedger *tokens.PrivateLedger vaultAddr address // address holding all deposited tokens vaulted = map[address]uint{} // still-locked deposits per owner pending = map[address]uint{} // amount marked for withdrawal unlockAt = map[address]int64{} // block height at which pending unlocks recoverOf = map[address]address{} // recovery address per depositor ) func init(cur realm) { // generate the token and mint some tokens to test1. Token, privateLedger = tokens.NewToken("Foo Token", "FOO", 4, 0, cur) privateLedger.Mint(test1, 100000000) // the vault holds deposited tokens at the realm's own address. vaultAddr = cur.Address() } func MyBalance() int64 { return Token.BalanceOf(unsafe.OriginCaller()) } // Deposit moves amount tokens from the caller into the vault, recording a // recovery address for later use. func Deposit(cur realm, amount uint, recoverAddress address) { caller := unsafe.OriginCaller() if err := privateLedger.Transfer(caller, vaultAddr, int64(amount)); err != nil { panic(err) } vaulted[caller] += amount recoverOf[caller] = recoverAddress } // Recover sends target's still-locked deposit to its recorded recovery address. func Recover(cur realm, target address) { amount := vaulted[target] if amount == 0 { return } dest := recoverOf[target] if err := privateLedger.Transfer(vaultAddr, dest, int64(amount)); err != nil { panic(err) } vaulted[target] = 0 } // Unvault marks amount of the caller's deposit for withdrawal and starts the // lock timer. func Unvault(cur realm, amount uint) { caller := unsafe.OriginCaller() if vaulted[caller] < amount { panic("insufficient vaulted balance") } vaulted[caller] -= amount pending[caller] += amount unlockAt[caller] = runtime.ChainHeight() + lockDuration } // Redeem transfers amount of the caller's matured pending withdrawal back to // the caller. func Redeem(cur realm, amount uint) { caller := unsafe.OriginCaller() if pending[caller] < amount { panic("insufficient pending balance") } if runtime.ChainHeight() < unlockAt[caller] { panic("still locked") } if err := privateLedger.Transfer(vaultAddr, caller, int64(amount)); err != nil { panic(err) } pending[caller] -= amount }
- #6gnomod.toml
- #7module = "gno.land/r/moul/demo/vault/v0" gno = "0.9"
- #8/gno.MemPackageType
- #9 MPUserProd
Result log
msg:0,success:true,log:,events:[]