Skip to content

Commit

Permalink
integrate stable cadence changes
Browse files Browse the repository at this point in the history
  • Loading branch information
joshuahannan committed Jul 18, 2023
1 parent e8f93ce commit 73a5ba8
Show file tree
Hide file tree
Showing 10 changed files with 148 additions and 145 deletions.
52 changes: 26 additions & 26 deletions contracts/ExampleToken-v2.cdc
Original file line number Diff line number Diff line change
@@ -1,22 +1,22 @@
import FungibleToken from "./FungibleToken-v2.cdc"
import MetadataViews from "./utility/MetadataViews.cdc"
import FungibleTokenMetadataViews from "./FungibleTokenMetadataViews.cdc"
import MultipleVaults from "./MultipleVaults.cdc"
import ViewResolver from "./utility/ViewResolver.cdc"
import FungibleToken from "FungibleToken-v2"
import MetadataViews from "MetadataViews"
import FungibleTokenMetadataViews from "FungibleTokenMetadataViews"
import MultipleVaults from "MultipleVaults.cdc"
import ViewResolver from "ViewResolver.cdc"

pub contract ExampleToken: ViewResolver, MultipleVaults {
access(all) contract ExampleToken: ViewResolver, MultipleVaults {

/// The event that is emitted when new tokens are minted
pub event TokensMinted(amount: UFix64, type: String)
access(all) event TokensMinted(amount: UFix64, type: String)

/// Total supply of ExampleTokens in existence
access(contract) var totalSupply: {Type: UFix64}

/// Admin Path
pub let AdminStoragePath: StoragePath
access(all) let AdminStoragePath: StoragePath

/// Function to return the types that the contract implements
pub fun getVaultTypes(): [Type] {
access(all) view fun getVaultTypes(): [Type] {
let typeArray: [Type] = [Type<@ExampleToken.Vault>()]
return typeArray
}
Expand All @@ -33,31 +33,31 @@ pub contract ExampleToken: ViewResolver, MultipleVaults {
/// out of thin air. A special Minter resource needs to be defined to mint
/// new tokens.
///
pub resource Vault: FungibleToken.Vault, FungibleToken.Provider, FungibleToken.Transferor, FungibleToken.Receiver, FungibleToken.Balance, ViewResolver.Resolver {
access(all) resource Vault: FungibleToken.Vault {

/// The total balance of this vault
pub var balance: UFix64
access(all) var balance: UFix64

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

/// Returns the storage path where the vault should typically be stored
pub fun getDefaultStoragePath(): StoragePath? {
access(all) view fun getDefaultStoragePath(): StoragePath? {
return self.storagePath
}

/// Returns the public path where this vault should have a public capability
pub fun getDefaultPublicPath(): PublicPath? {
access(all) view fun getDefaultPublicPath(): PublicPath? {
return self.publicPath
}

pub fun getViews(): [Type] {
access(all) view fun getViews(): [Type] {
return [Type<FungibleTokenMetadataViews.FTView>(),
Type<FungibleTokenMetadataViews.FTDisplay>(),
Type<FungibleTokenMetadataViews.FTVaultData>()]
}

pub fun resolveView(_ view: Type): AnyStruct? {
access(all) view fun resolveView(_ view: Type): AnyStruct? {
switch view {
case Type<FungibleTokenMetadataViews.FTView>():
return FungibleTokenMetadataViews.FTView(
Expand Down Expand Up @@ -93,7 +93,7 @@ pub contract ExampleToken: ViewResolver, MultipleVaults {
receiverLinkedType: Type<&ExampleToken.Vault{FungibleToken.Receiver}>(),
metadataLinkedType: Type<&ExampleToken.Vault{FungibleToken.Balance, ViewResolver.Resolver}>(),
providerLinkedType: Type<&ExampleToken.Vault{FungibleToken.Provider}>(),
createEmptyVaultFunction: (fun (): @ExampleToken.Vault{FungibleToken.Vault} {
createEmptyVaultFunction: (fun(): @ExampleToken.Vault{FungibleToken.Vault} {
return <-vaultRef.createEmptyVault()
})
)
Expand All @@ -102,13 +102,13 @@ pub contract ExampleToken: ViewResolver, MultipleVaults {
}

/// getSupportedVaultTypes optionally returns a list of vault types that this receiver accepts
pub fun getSupportedVaultTypes(): {Type: Bool} {
access(all) view fun getSupportedVaultTypes(): {Type: Bool} {
let supportedTypes: {Type: Bool} = {}
supportedTypes[self.getType()] = true
return supportedTypes
}

pub fun isSupportedVaultType(type: Type): Bool {
access(all) view fun isSupportedVaultType(type: Type): Bool {
return self.getSupportedVaultTypes()[type] ?? false
}

Expand All @@ -121,7 +121,7 @@ pub contract ExampleToken: ViewResolver, MultipleVaults {
}

/// Get the balance of the vault
pub fun getBalance(): UFix64 {
access(all) view fun getBalance(): UFix64 {
return self.balance
}

Expand All @@ -135,7 +135,7 @@ pub contract ExampleToken: ViewResolver, MultipleVaults {
/// created Vault to the context that called so it can be deposited
/// elsewhere.
///
pub fun withdraw(amount: UFix64): @ExampleToken.Vault{FungibleToken.Vault} {
access(FungibleToken.Withdrawable) fun withdraw(amount: UFix64): @ExampleToken.Vault{FungibleToken.Vault} {
self.balance = self.balance - amount
return <-create Vault(balance: amount)
}
Expand All @@ -149,14 +149,14 @@ pub contract ExampleToken: ViewResolver, MultipleVaults {
/// was a temporary holder of the tokens. The Vault's balance has
/// been consumed and therefore can be destroyed.
///
pub fun deposit(from: @AnyResource{FungibleToken.Vault}) {
access(all) fun deposit(from: @AnyResource{FungibleToken.Vault}) {
let vault <- from as! @ExampleToken.Vault
self.balance = self.balance + vault.balance
vault.balance = 0.0
destroy vault
}

pub fun transfer(amount: UFix64, receiver: Capability<&{FungibleToken.Receiver}>) {
access(all) fun transfer(amount: UFix64, receiver: Capability<&{FungibleToken.Receiver}>) {
let transferVault <- self.withdraw(amount: amount)

// Get a reference to the recipient's Receiver
Expand All @@ -174,7 +174,7 @@ pub contract ExampleToken: ViewResolver, MultipleVaults {
/// and store the returned Vault in their storage in order to allow their
/// account to be able to receive deposits of this token type.
///
pub fun createEmptyVault(): @ExampleToken.Vault{FungibleToken.Vault} {
access(all) fun createEmptyVault(): @ExampleToken.Vault{FungibleToken.Vault} {
return <-create Vault(balance: 0.0)
}

Expand All @@ -189,13 +189,13 @@ pub contract ExampleToken: ViewResolver, MultipleVaults {
///
/// Resource object that token admin accounts can hold to mint new tokens.
///
pub resource Minter {
access(all) resource Minter {
/// mintTokens
///
/// Function that mints new tokens, adds them to the total supply,
/// and returns them to the calling context.
///
pub fun mintTokens(amount: UFix64): @ExampleToken.Vault {
access(all) fun mintTokens(amount: UFix64): @ExampleToken.Vault {
ExampleToken.totalSupply[self.getType()] = ExampleToken.totalSupply[self.getType()]! + amount
emit TokensMinted(amount: amount, type: self.getType().identifier)
return <-create Vault(balance: amount)
Expand All @@ -209,7 +209,7 @@ pub contract ExampleToken: ViewResolver, MultipleVaults {
/// and store the returned Vault in their storage in order to allow their
/// account to be able to receive deposits of this token type.
///
pub fun createEmptyVault(vaultType: Type): @{FungibleToken.Vault} {
access(all) fun createEmptyVault(vaultType: Type): @{FungibleToken.Vault} {
switch vaultType {
case Type<@ExampleToken.Vault>():
return <- create Vault(balance: 0.0)
Expand Down
2 changes: 1 addition & 1 deletion contracts/ExampleToken.cdc
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,7 @@ access(all) contract ExampleToken: FungibleToken {
receiverLinkedType: Type<&ExampleToken.Vault{FungibleToken.Receiver}>(),
metadataLinkedType: Type<&ExampleToken.Vault{FungibleToken.Balance, MetadataViews.Resolver}>(),
providerLinkedType: Type<&ExampleToken.Vault{FungibleToken.Provider}>(),
createEmptyVaultFunction: (fun (): @ExampleToken.Vault {
createEmptyVaultFunction: (fun(): @ExampleToken.Vault {
return <-ExampleToken.createEmptyVault()
})
)
Expand Down
67 changes: 35 additions & 32 deletions contracts/FungibleToken-v2.cdc
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ to the Provider interface.
*/

import ViewResolver from "./utility/ViewResolver.cdc"
import ViewResolver from "ViewResolver"

/// FungibleToken
///
Expand All @@ -40,31 +40,34 @@ import ViewResolver from "./utility/ViewResolver.cdc"
/// utility methods that many projects will still want to have on their contracts,
/// but they are by no means required. all that is required is that the token
/// implements the `Vault` interface
pub contract FungibleToken {
access(all) contract FungibleToken {

// An entitlement for allowing the withdrawal of tokens from a Vault
access(all) entitlement Withdrawable

/// The event that is emitted when tokens are withdrawn from a Vault
pub event Withdraw(amount: UFix64, from: Address?, type: String)
access(all) event Withdraw(amount: UFix64, from: Address?, type: String)
access(self) fun emitWithdrawEvent(amount: UFix64, from: Address?, type: String): Bool {
emit Withdraw(amount: amount, from: from, type: type)
return true
}

/// The event that is emitted when tokens are deposited to a Vault
pub event Deposit(amount: UFix64, to: Address?, type: String)
access(all) event Deposit(amount: UFix64, to: Address?, type: String)
access(self) fun emitDepositEvent(amount: UFix64, to: Address?, type: String): Bool {
emit Deposit(amount: amount, to: to, type: type)
return true
}

/// The event that is emitted when tokens are transferred from one account to another
pub event Transfer(amount: UFix64, from: Address?, to: Address?, type: String)
access(all) event Transfer(amount: UFix64, from: Address?, to: Address?, type: String)
access(self) fun emitTransferEvent(amount: UFix64, from: Address?, to: Address?, type: String): Bool {
emit Transfer(amount: amount, from: from, to: to, type: type)
return true
}

/// Event emitted when tokens are destroyed
pub event Burn(amount: UFix64, type: String)
access(all) event Burn(amount: UFix64, type: String)

access(self) fun emitBurnEvent(amount: UFix64, type: String): Bool {
if amount >= 0.0 {
Expand All @@ -82,7 +85,7 @@ pub contract FungibleToken {
/// because it leaves open the possibility of creating custom providers
/// that do not necessarily need their own balance.
///
pub resource interface Provider {
access(all) resource interface Provider {

/// withdraw subtracts tokens from the owner's Vault
/// and returns a Vault with the removed tokens.
Expand All @@ -99,7 +102,7 @@ pub contract FungibleToken {
/// capability that allows all users to access the provider
/// resource through a reference.
///
pub fun withdraw(amount: UFix64): @AnyResource{Vault} {
access(Withdrawable) fun withdraw(amount: UFix64): @AnyResource{Vault} {
post {
// `result` refers to the return value
result.getBalance() == amount:
Expand All @@ -119,14 +122,14 @@ pub contract FungibleToken {
/// can do custom things with the tokens, like split them up and
/// send them to different places.
///
pub resource interface Receiver {
access(all) resource interface Receiver {

/// deposit takes a Vault and deposits it into the implementing resource type
///
pub fun deposit(from: @AnyResource{Vault})
access(all) fun deposit(from: @AnyResource{Vault})

/// getSupportedVaultTypes optionally returns a list of vault types that this receiver accepts
pub fun getSupportedVaultTypes(): {Type: Bool} {
access(all) view fun getSupportedVaultTypes(): {Type: Bool} {
// Below check is implemented to make sure that run-time type would
// only get returned when the parent resource conforms with `FungibleToken.Vault`.
if self.getType().isSubtype(of: Type<@AnyResource{FungibleToken.Vault}>()) {
Expand All @@ -140,15 +143,15 @@ pub contract FungibleToken {

/// Returns whether or not the given type is accepted by the Receiver
/// A vault that can accept any type should just return true by default
pub fun isSupportedVaultType(type: Type): Bool {
access(all) view fun isSupportedVaultType(type: Type): Bool {
return false
}
}

pub resource interface Transferor {
access(all) resource interface Transferor {
/// Function for a direct transfer instead of having to do a deposit and withdrawal
///
pub fun transfer(amount: UFix64, receiver: Capability<&{FungibleToken.Receiver}>) {
access(all) fun transfer(amount: UFix64, receiver: Capability<&{FungibleToken.Receiver}>) {
pre {
receiver.check(): "Could not borrow a reference to the NFT receiver"
}
Expand All @@ -160,54 +163,54 @@ pub contract FungibleToken {
/// This interface is now a general purpose metadata interface because
/// a public interface is needed to get metadata, but adding a whole new interface
/// for every account to upgrade to is probably too much of a breaking change
pub resource interface Balance { //: ViewResolver.Resolver {
access(all) resource interface Balance { //: ViewResolver.Resolver {
/// Method to get the balance
/// The balance could be a derived field,
/// so there is no need to require an explicit field
pub fun getBalance(): UFix64
access(all) view fun getBalance(): UFix64

pub fun getSupportedVaultTypes(): {Type: Bool}
pub fun isSupportedVaultType(type: Type): Bool
access(all) view fun getSupportedVaultTypes(): {Type: Bool}
access(all) view fun isSupportedVaultType(type: Type): Bool

/// ViewResolver Methods
///
pub fun getViews(): [Type]
pub fun resolveView(_ view: Type): AnyStruct?
access(all) view fun getViews(): [Type]
access(all) view fun resolveView(_ view: Type): AnyStruct?
}

/// Vault
///
/// Ideally, this interface would also conform to Receiver, Balance, Transferor, Provider, and Resolver
/// but that is not supported yet
///
pub resource interface Vault { //: Receiver, Balance, Transferor, Provider, ViewResolver.Resolver {
access(all) resource interface Vault: Receiver, Balance, Transferor, Provider, ViewResolver.Resolver {

/// Get the balance of the vault
pub fun getBalance(): UFix64
access(all) view fun getBalance(): UFix64

/// getSupportedVaultTypes optionally returns a list of vault types that this receiver accepts
pub fun getSupportedVaultTypes(): {Type: Bool}
access(all) view fun getSupportedVaultTypes(): {Type: Bool}

pub fun isSupportedVaultType(type: Type): Bool
access(all) view fun isSupportedVaultType(type: Type): Bool

/// Returns the storage path where the vault should typically be stored
pub fun getDefaultStoragePath(): StoragePath? {
access(all) view fun getDefaultStoragePath(): StoragePath? {
return nil
}

/// Returns the public path where this vault should have a public capability
pub fun getDefaultPublicPath(): PublicPath? {
access(all) view fun getDefaultPublicPath(): PublicPath? {
return nil
}

pub fun getViews(): [Type]
pub fun resolveView(_ view: Type): AnyStruct?
access(all) view fun getViews(): [Type]
access(all) view fun resolveView(_ view: Type): AnyStruct?

/// withdraw subtracts `amount` from the Vault's balance
/// and returns a new Vault with the subtracted balance
///
pub fun withdraw(amount: UFix64): @AnyResource{Vault} {
access(Withdrawable) fun withdraw(amount: UFix64): @AnyResource{Vault} {
pre {
self.getBalance() >= amount:
"Amount withdrawn must be less than or equal than the balance of the Vault"
Expand All @@ -223,7 +226,7 @@ pub contract FungibleToken {

/// deposit takes a Vault and adds its balance to the balance of this Vault
///
pub fun deposit(from: @AnyResource{FungibleToken.Vault}) {
access(all) fun deposit(from: @AnyResource{FungibleToken.Vault}) {
// Assert that the concrete type of the deposited vault is the same
// as the vault that is accepting the deposit
pre {
Expand All @@ -239,7 +242,7 @@ pub contract FungibleToken {

/// Function for a direct transfer instead of having to do a deposit and withdrawal
///
pub fun transfer(amount: UFix64, receiver: Capability<&{FungibleToken.Receiver}>) {
access(all) fun transfer(amount: UFix64, receiver: Capability<&{FungibleToken.Receiver}>) {
post {
self.getBalance() == before(self.getBalance()) - amount:
"New Vault balance from the sender must be the difference of the previous balance and the withdrawn Vault balance"
Expand All @@ -249,7 +252,7 @@ pub contract FungibleToken {

/// createEmptyVault allows any user to create a new Vault that has a zero balance
///
pub fun createEmptyVault(): @AnyResource{Vault} {
access(all) fun createEmptyVault(): @AnyResource{Vault} {
post {
result.getBalance() == 0.0: "The newly created Vault must have zero balance"
}
Expand Down
Loading

0 comments on commit 73a5ba8

Please sign in to comment.