Skip to content

Commit

Permalink
remove event functions, make update access contract, fix some tests
Browse files Browse the repository at this point in the history
  • Loading branch information
joshuahannan committed Jan 25, 2024
1 parent 2118663 commit d2b571f
Show file tree
Hide file tree
Showing 9 changed files with 275 additions and 278 deletions.
20 changes: 10 additions & 10 deletions contracts/ExampleNFT.cdc
Original file line number Diff line number Diff line change
Expand Up @@ -55,8 +55,8 @@ access(all) contract ExampleNFT: NonFungibleToken {
/// createEmptyCollection creates an empty Collection
/// and returns it to the caller so that they can own NFTs
/// @{NonFungibleToken.Collection}
access(all) fun createEmptyCollection(): @ExampleNFT.Collection {
return <-ExampleNFT.createEmptyCollection()
access(all) fun createEmptyCollection(): @{NonFungibleToken.Collection} {
return <-ExampleNFT.createEmptyCollection(nftType: Type<@ExampleNFT.NFT>())
}

access(all) view fun getViews(): [Type] {
Expand Down Expand Up @@ -129,8 +129,8 @@ access(all) contract ExampleNFT: NonFungibleToken {
/// NFT is a resource type with an `UInt64` ID field
access(contract) var ownedNFTs: @{UInt64: ExampleNFT.NFT}

access(self) var storagePath: StoragePath
access(self) var publicPath: PublicPath
access(all) var storagePath: StoragePath
access(all) var publicPath: PublicPath

init () {
self.ownedNFTs <- {}
Expand Down Expand Up @@ -200,8 +200,8 @@ access(all) contract ExampleNFT: NonFungibleToken {
/// createEmptyCollection creates an empty Collection of the same type
/// and returns it to the caller
/// @return A an empty collection of the same type
access(all) fun createEmptyCollection(): @{Collection} {
return <-ExampleNFT.createEmptyCollection(nftType: )
access(all) fun createEmptyCollection(): @{NonFungibleToken.Collection} {
return <-ExampleNFT.createEmptyCollection(nftType: Type<@ExampleNFT.NFT>())
}
}

Expand Down Expand Up @@ -235,8 +235,8 @@ access(all) contract ExampleNFT: NonFungibleToken {
from: /storage/cadenceExampleNFTCollection
) ?? panic("Could not borrow a reference to the stored collection")
let collectionData = MetadataViews.NFTCollectionData(
storagePath: collectionRef.getDefaultStoragePath()!,
publicPath: collectionRef.getDefaultPublicPath()!,
storagePath: collectionRef.storagePath,
publicPath: collectionRef.publicPath,
publicCollection: Type<&ExampleNFT.Collection>(),
publicLinkedType: Type<&ExampleNFT.Collection>(),
createEmptyCollectionFunction: (fun(): @{NonFungibleToken.Collection} {
Expand Down Expand Up @@ -307,8 +307,8 @@ access(all) contract ExampleNFT: NonFungibleToken {

// Create a Collection resource and save it to storage
let collection <- create Collection()
let defaultStoragePath = collection.getDefaultStoragePath()!
let defaultPublicPath = collection.getDefaultPublicPath()!
let defaultStoragePath = collection.storagePath
let defaultPublicPath = collection.publicPath
self.account.storage.save(<-collection, to: defaultStoragePath)

// create a public capability for the collection
Expand Down
16 changes: 1 addition & 15 deletions contracts/NonFungibleToken.cdc
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ access(all) contract interface NonFungibleToken: ViewResolver {
/// and query the updated metadata from the owners' collections.
///
access(all) event Updated(type: String, id: UInt64, uuid: UInt64, owner: Address?)
access(all) view fun emitNFTUpdated(_ nftRef: auth(Update | Owner) &{NonFungibleToken.NFT})
access(contract) view fun emitNFTUpdated(_ nftRef: auth(Update | Owner) &{NonFungibleToken.NFT})
{
emit Updated(type: nftRef.getType().identifier, id: nftRef.id, uuid: nftRef.uuid, owner: nftRef.owner?.address)
}
Expand All @@ -76,12 +76,6 @@ access(all) contract interface NonFungibleToken: ViewResolver {
/// If the collection is not in an account's storage, `from` will be `nil`.
///
access(all) event Withdrawn(type: String, id: UInt64, uuid: UInt64, from: Address?, providerUUID: UInt64)
// access(contract) view fun emitWithdrawnEvent(type: String, id: UInt64, uuid: UInt64, from: Address?, providerUUID: UInt64): Bool {
// if from != nil {
// emit Withdrawn(type: type, id: id, uuid: uuid, from: from, providerUUID: providerUUID)
// }
// return true
// }

/// Event that emitted when a token is deposited to a collection.
/// Indicates the type, id, uuid, the owner of the collection that it was deposited to,
Expand All @@ -90,12 +84,6 @@ access(all) contract interface NonFungibleToken: ViewResolver {
/// If the collection is not in an account's storage, `from`, will be `nil`.
///
access(all) event Deposited(type: String, id: UInt64, uuid: UInt64, to: Address?, collectionUUID: UInt64)
// access(contract) view fun emitDepositedEvent(type: String, id: UInt64, uuid: UInt64, to: Address?, collectionUUID: UInt64): Bool {
// if to != nil {
// emit Deposited(type: type, id: id, uuid: uuid, to: to, collectionUUID: collectionUUID)
// }
// return true
// }

/// Included for backwards-compatibility
access(all) resource interface INFT: NFT {}
Expand Down Expand Up @@ -156,7 +144,6 @@ access(all) contract interface NonFungibleToken: ViewResolver {
access(Withdraw | Owner) fun withdraw(withdrawID: UInt64): @{NFT} {
post {
result.id == withdrawID: "The ID of the withdrawn token must be the same as the requested ID"
//emitWithdrawnEvent(type: result.getType().identifier, id: result.id, uuid: result.uuid, from: self.owner?.address, providerUUID: self.uuid)
emit Withdrawn(type: result.getType().identifier, id: result.id, uuid: result.uuid, from: self.owner?.address, providerUUID: self.uuid)
}
}
Expand Down Expand Up @@ -195,7 +182,6 @@ access(all) contract interface NonFungibleToken: ViewResolver {
// because the `Collection` interface is almost always the final destination
// of tokens and deposit emissions from custom receivers could be confusing
// and hard to reconcile to event listeners
//emitDepositedEvent(type: token.getType().identifier, id: token.id, uuid: token.uuid, to: self.owner?.address, collectionUUID: self.uuid)
emit Deposited(type: token.getType().identifier, id: token.id, uuid: token.uuid, to: self.owner?.address, collectionUUID: self.uuid)
}
}
Expand Down
66 changes: 39 additions & 27 deletions contracts/utility/FungibleToken.cdc
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ to the Provider interface.
*/

import ViewResolver from "ViewResolver"
// import Burner from "Burner"
/// FungibleToken
///
Expand All @@ -46,22 +47,21 @@ access(all) contract interface FungibleToken: ViewResolver {
access(all) entitlement Withdraw

/// The event that is emitted when tokens are withdrawn from a Vault
access(all) event Withdrawn(amount: UFix64, type: String, from: Address?, fromUUID: UInt64, withdrawnUUID: UInt64)
access(all) event Withdrawn(type: String, amount: UFix64, from: Address?, fromUUID: UInt64, withdrawnUUID: UInt64)

/// The event that is emitted when tokens are deposited to a Vault
access(all) event Deposited(amount: UFix64, type: String, to: Address?, toUUID: UInt64, depositedUUID: UInt64)
access(all) event Deposited(type: String, amount: UFix64, to: Address?, toUUID: UInt64, depositedUUID: UInt64)

/// Event that is emitted when the global burn method is called with a non-zero balance
access(all) event Burned(amount: UFix64, type: String, fromUUID: UInt64)
access(all) event Burned(type: String, amount: UFix64, fromUUID: UInt64)

/// Balance
///
/// The interface that provides standard functions\
/// for getting balance information
///
access(all) resource interface Balance {
/// Get the balance of the vault
access(all) view fun getBalance(): UFix64
access(all) var balance: UFix64
}

/// Provider
Expand All @@ -75,6 +75,16 @@ access(all) contract interface FungibleToken: ViewResolver {
///
access(all) resource interface Provider {

/// Function to ask a provider if a specific amount of tokens
/// is available to be withdrawn
/// This could be useful to avoid panicing when calling withdraw
/// when the balance is unknown
/// Additionally, if the provider is pulling from multiple vaults
/// it only needs to check some of the vaults until the desired amount
/// is reached, potentially helping with performance.
///
access(all) view fun isAvailableToWithdraw(amount: UFix64): Bool

/// withdraw subtracts tokens from the implementing resource
/// and returns a Vault with the removed tokens.
///
Expand All @@ -85,9 +95,9 @@ access(all) contract interface FungibleToken: ViewResolver {
access(Withdraw) fun withdraw(amount: UFix64): @{Vault} {
post {
// `result` refers to the return value
result.getBalance() == amount:
result.balance == amount:
"Withdrawal amount must be the same as the balance of the withdrawn Vault"
emit Withdrawn(amount: amount, type: self.getType().identifier, from: self.owner?.address, fromUUID: self.uuid, withdrawnUUID: result.uuid)
emit Withdrawn(type: self.getType().identifier, amount: amount, from: self.owner?.address, fromUUID: self.uuid, withdrawnUUID: result.uuid)
}
}
}
Expand Down Expand Up @@ -121,13 +131,26 @@ access(all) contract interface FungibleToken: ViewResolver {
/// Ideally, this interface would also conform to Receiver, Balance, Transferor, Provider, and Resolver
/// but that is not supported yet
///
access(all) resource interface Vault: Receiver, Provider, Balance, ViewResolver.Resolver {
access(all) resource interface Vault: Receiver, Provider, Balance, ViewResolver.Resolver { //, Burner.Burnable {
/// Field that tracks the balance of a vault
access(all) var balance: UFix64

/// Get the balance of the vault
access(all) view fun getBalance(): UFix64
/// Called when a fungible token is burned via the `Burner.burn()` method
/// Implementations can do any bookkeeping or emit any events
/// that should be emitted when a vault is destroyed.
/// Many implementations will want to update the token's total supply
/// to reflect that the tokens have been burned and removed from the supply.
/// Implementations also need to set the balance to zero before the end of the function
/// This is to prevent vault owners from spamming fake Burned events.
access(contract) fun burnCallback() {
pre {
emit Burned(type: self.getType().identifier, amount: self.balance, fromUUID: self.uuid)
}
post {
self.balance == 0.0: "The balance must be set to zero during the burnCallback method so that it cannot be spammed"
}
}

/// getSupportedVaultTypes optionally returns a list of vault types that this receiver accepts
/// The default implementation is included here because vaults are expected
Expand Down Expand Up @@ -155,14 +178,14 @@ access(all) contract interface FungibleToken: ViewResolver {
///
access(Withdraw) fun withdraw(amount: UFix64): @{Vault} {
pre {
self.getBalance() >= amount:
self.balance >= amount:
"Amount withdrawn must be less than or equal than the balance of the Vault"
}
post {
// use the special function `before` to get the value of the `balance` field
// at the beginning of the function execution
//
self.getBalance() == before(self.getBalance()) - amount:
self.balance == before(self.balance) - amount:
"New Vault balance must be the difference of the previous balance and the withdrawn Vault balance"
}
}
Expand All @@ -175,10 +198,10 @@ access(all) contract interface FungibleToken: ViewResolver {
pre {
from.isInstance(self.getType()):
"Cannot deposit an incompatible token type"
emit Deposited(amount: from.getBalance(), type: from.getType().identifier, to: self.owner?.address, toUUID: self.uuid, depositedUUID: from.uuid)
emit Deposited(type: from.getType().identifier, amount: from.balance, to: self.owner?.address, toUUID: self.uuid, depositedUUID: from.uuid)
}
post {
self.getBalance() == before(self.getBalance()) + before(from.getBalance()):
self.balance == before(self.balance) + before(from.balance):
"New Vault balance must be the sum of the previous balance and the deposited Vault"
}
}
Expand All @@ -187,7 +210,7 @@ access(all) contract interface FungibleToken: ViewResolver {
///
access(all) fun createEmptyVault(): @{Vault} {
post {
result.getBalance() == 0.0: "The newly created Vault must have zero balance"
result.balance == 0.0: "The newly created Vault must have zero balance"
}
}
}
Expand All @@ -197,18 +220,7 @@ access(all) contract interface FungibleToken: ViewResolver {
access(all) fun createEmptyVault(vaultType: Type): @{FungibleToken.Vault} {
post {
result.getType() == vaultType: "The returned vault does not match the desired type"
result.getBalance() == 0.0: "The newly created Vault must have zero balance"
}
}

/// Method to burn a FungibleToken Vault
/// contract implementations should provide an implementation for this function
/// that subtracts the vault balance from the token's total supply
access(all) fun burn(_ vault: @{FungibleToken.Vault}) {
pre {
self.getVaultTypes().contains(vault.getType())
vault.balance > 0.0: "Do not use the burn method unless the vault balance is greater than zero!"
emit Burned(amount: vault.balance, type: vault.getType().identifier, fromUUID: vault.uuid)
result.balance == 0.0: "The newly created Vault must have zero balance"
}
}
}
30 changes: 22 additions & 8 deletions flow.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,21 +10,21 @@
"source": "./contracts/NonFungibleToken.cdc",
"aliases": {
"emulator": "0xf8d6e0586b0a20c7",
"testing": "0x0000000000000001",
"testing": "0x0000000000000007",
"testnet": "0x631e88ae7f1d7c20",
"mainnet": "0x1d7e57aa55817448"
}
},
"MetadataViews": {
"source": "./contracts/MetadataViews.cdc",
"aliases": {
"testing": "0x0000000000000001"
"testing": "0x0000000000000007"
}
},
"ViewResolver": {
"source": "./contracts/ViewResolver.cdc",
"aliases": {
"testing": "0x0000000000000001"
"testing": "0x0000000000000007"
}
},
"ExampleNFT": {
Expand All @@ -33,10 +33,22 @@
"testing": "0x0000000000000007"
}
},
"UniversalCollection": {
"source": "./contracts/UniversalCollection.cdc",
"aliases": {
"testing": "0x0000000000000007"
}
},
"BasicNFT": {
"source": "./contracts/BasicNFT.cdc",
"aliases": {
"testing": "0x0000000000000007"
}
},
"FungibleToken": {
"source": "./contracts/utility/FungibleToken.cdc",
"aliases": {
"testing": "0x0000000000000002"
"testing": "0x0000000000000007"
}
},
"NFTForwarding": {
Expand All @@ -61,12 +73,14 @@
"deployments": {
"emulator": {
"emulator-account": [
"NonFungibleToken",
"ViewResolver",
"ExampleNFT",
"MetadataViews",
"NonFungibleToken",
"FungibleToken",
"NFTForwarding"
"MetadataViews",
"ExampleNFT",
"NFTForwarding",
"UniversalCollection",
"BasicNFT"
]
}
}
Expand Down
Loading

0 comments on commit d2b571f

Please sign in to comment.