From 32d51d2f5a3fb442e2086ee8eda0530f2815a430 Mon Sep 17 00:00:00 2001 From: Jordan Ribbink Date: Wed, 10 Jan 2024 22:21:54 -0800 Subject: [PATCH] Remove FUSD --- .env.development | 1 - .env.example | 1 - cadence/contracts/FUSD.cdc | 226 ----------------------------- cadence/scripts/checkFUSDVault.cdc | 12 -- cadence/scripts/getFUSDBalance.cdc | 7 - cadence/transactions/fundFUSD.cdc | 52 ------- components/AccountBalances.tsx | 22 +-- contexts/ConfigContext.tsx | 2 - flow.json | 9 -- go/wallet/.env.development | 1 - hooks/useFUSDBalance.ts | 40 ----- next.config.js | 1 - src/accounts.ts | 31 +--- src/constants.ts | 5 +- 14 files changed, 6 insertions(+), 404 deletions(-) delete mode 100644 cadence/contracts/FUSD.cdc delete mode 100644 cadence/scripts/checkFUSDVault.cdc delete mode 100644 cadence/scripts/getFUSDBalance.cdc delete mode 100644 cadence/transactions/fundFUSD.cdc delete mode 100644 hooks/useFUSDBalance.ts diff --git a/.env.development b/.env.development index c8f8ad1..a0cf664 100644 --- a/.env.development +++ b/.env.development @@ -5,7 +5,6 @@ FLOW_INIT_ACCOUNTS=0 CONTRACT_FUNGIBLE_TOKEN=0xee82856bf20e2aa6 CONTRACT_FLOW_TOKEN=0x0ae53cb6e3f42a79 -CONTRACT_FUSD=0xf8d6e0586b0a20c7 CONTRACT_FCL_CRYPTO=0xf8d6e0586b0a20c7 FLOW_AVATAR_URL=https://avatars.onflow.org/avatar/ diff --git a/.env.example b/.env.example index 820d846..685347b 100644 --- a/.env.example +++ b/.env.example @@ -5,7 +5,6 @@ FLOW_INIT_ACCOUNTS=0 CONTRACT_FUNGIBLE_TOKEN=0xee82856bf20e2aa6 CONTRACT_FLOW_TOKEN=0x0ae53cb6e3f42a79 -CONTRACT_FUSD=0xf8d6e0586b0a20c7 CONTRACT_FCL_CRYPTO=0xf8d6e0586b0a20c7 FLOW_AVATAR_URL=https://avatars.onflow.org/avatar/ diff --git a/cadence/contracts/FUSD.cdc b/cadence/contracts/FUSD.cdc deleted file mode 100644 index b75c8fb..0000000 --- a/cadence/contracts/FUSD.cdc +++ /dev/null @@ -1,226 +0,0 @@ -import FungibleToken from "./FungibleToken.cdc" - -pub contract FUSD: FungibleToken { - - // Event that is emitted when the contract is created - pub event TokensInitialized(initialSupply: UFix64) - - // Event that is emitted when tokens are withdrawn from a Vault - pub event TokensWithdrawn(amount: UFix64, from: Address?) - - // Event that is emitted when tokens are deposited to a Vault - pub event TokensDeposited(amount: UFix64, to: Address?) - - // Event that is emitted when new tokens are minted - pub event TokensMinted(amount: UFix64) - - // The storage path for the admin resource - pub let AdminStoragePath: StoragePath - - // The storage Path for minters' MinterProxy - pub let MinterProxyStoragePath: StoragePath - - // The public path for minters' MinterProxy capability - pub let MinterProxyPublicPath: PublicPath - - // Event that is emitted when a new minter resource is created - pub event MinterCreated() - - // Total supply of fusd in existence - pub var totalSupply: UFix64 - - // Vault - // - // Each user stores an instance of only the Vault in their storage - // The functions in the Vault are governed by the pre and post conditions - // in FungibleToken when they are called. - // The checks happen at runtime whenever a function is called. - // - // Resources can only be created in the context of the contract that they - // are defined in, so there is no way for a malicious user to create Vaults - // out of thin air. A special Minter resource needs to be defined to mint - // new tokens. - // - pub resource Vault: FungibleToken.Provider, FungibleToken.Receiver, FungibleToken.Balance { - - // holds the balance of a users tokens - pub var balance: UFix64 - - // initialize the balance at resource creation time - init(balance: UFix64) { - self.balance = balance - } - - // withdraw - // - // Function that takes an integer amount as an argument - // and withdraws that amount from the Vault. - // It creates a new temporary Vault that is used to hold - // the money that is being transferred. It returns the newly - // created Vault to the context that called so it can be deposited - // elsewhere. - // - pub fun withdraw(amount: UFix64): @FungibleToken.Vault { - self.balance = self.balance - amount - emit TokensWithdrawn(amount: amount, from: self.owner?.address) - return <-create Vault(balance: amount) - } - - // deposit - // - // Function that takes a Vault object as an argument and adds - // its balance to the balance of the owners Vault. - // It is allowed to destroy the sent Vault because the Vault - // was a temporary holder of the tokens. The Vault's balance has - // been consumed and therefore can be destroyed. - pub fun deposit(from: @FungibleToken.Vault) { - let vault <- from as! @FUSD.Vault - self.balance = self.balance + vault.balance - emit TokensDeposited(amount: vault.balance, to: self.owner?.address) - vault.balance = 0.0 - destroy vault - } - - destroy() { - FUSD.totalSupply = FUSD.totalSupply - self.balance - } - } - - // createEmptyVault - // - // Function that creates a new Vault with a balance of zero - // and returns it to the calling context. A user must call this function - // 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(): @FUSD.Vault { - return <-create Vault(balance: 0.0) - } - - // Minter - // - // Resource object that can mint new tokens. - // The admin stores this and passes it to the minter account as a capability wrapper resource. - // - pub 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): @FUSD.Vault { - pre { - amount > 0.0: "Amount minted must be greater than zero" - } - FUSD.totalSupply = FUSD.totalSupply + amount - emit TokensMinted(amount: amount) - return <-create Vault(balance: amount) - } - - } - - pub resource interface MinterProxyPublic { - pub fun setMinterCapability(cap: Capability<&Minter>) - } - - // MinterProxy - // - // Resource object holding a capability that can be used to mint new tokens. - // The resource that this capability represents can be deleted by the admin - // in order to unilaterally revoke minting capability if needed. - - pub resource MinterProxy: MinterProxyPublic { - - // access(self) so nobody else can copy the capability and use it. - access(self) var minterCapability: Capability<&Minter>? - - // Anyone can call this, but only the admin can create Minter capabilities, - // so the type system constrains this to being called by the admin. - pub fun setMinterCapability(cap: Capability<&Minter>) { - self.minterCapability = cap - } - - pub fun mintTokens(amount: UFix64): @FUSD.Vault { - return <- self.minterCapability! - .borrow()! - .mintTokens(amount:amount) - } - - init() { - self.minterCapability = nil - } - - } - - // createMinterProxy - // - // Function that creates a MinterProxy. - // Anyone can call this, but the MinterProxy cannot mint without a Minter capability, - // and only the admin can provide that. - // - pub fun createMinterProxy(): @MinterProxy { - return <- create MinterProxy() - } - - // Administrator - // - // A resource that allows new minters to be created - // - // We will only want one minter for now, but might need to add or replace them in future. - // The Minter/Minter Proxy structure enables this. - // Ideally we would create this structure in a single function, generate the paths from the address - // and cache all of this information to enable easy revocation but String/Path comversion isn't yet supported. - // - pub resource Administrator { - - // createNewMinter - // - // Function that creates a Minter resource. - // This should be stored at a unique path in storage then a capability to it wrapped - // in a MinterProxy to be stored in a minter account's storage. - // This is done by the minter account running: - // transactions/fusd/minter/setup_minter_account.cdc - // then the admin account running: - // transactions/fusd/admin/deposit_minter_capability.cdc - // - pub fun createNewMinter(): @Minter { - emit MinterCreated() - return <- create Minter() - } - - } - - init() { - self.AdminStoragePath = /storage/fusdAdmin - self.MinterProxyPublicPath = /public/fusdMinterProxy - self.MinterProxyStoragePath = /storage/fusdMinterProxy - - self.totalSupply = 0.0 - - let admin <- create Administrator() - - // Emit an event that shows that the contract was initialized - emit TokensInitialized(initialSupply: 0.0) - - let minter <- admin.createNewMinter() - - let mintedVault <- minter.mintTokens(amount: 1000000.0) - - destroy minter - - self.account.save(<-admin, to: self.AdminStoragePath) - - self.account.save(<-mintedVault, to: /storage/fusdVault) - - self.account.link<&FUSD.Vault{FungibleToken.Receiver}>( - /public/fusdReceiver, - target: /storage/fusdVault - ) - - self.account.link<&FUSD.Vault{FungibleToken.Balance}>( - /public/fusdBalance, - target: /storage/fusdVault - ) - } -} diff --git a/cadence/scripts/checkFUSDVault.cdc b/cadence/scripts/checkFUSDVault.cdc deleted file mode 100644 index e00730c..0000000 --- a/cadence/scripts/checkFUSDVault.cdc +++ /dev/null @@ -1,12 +0,0 @@ -import FUSD from 0xFUSDADDRESS -import FungibleToken from 0xFUNGIBLETOKENADDRESS - -pub fun main(address: Address): Bool { - let receiver = getAccount(address) - .getCapability<&FUSD.Vault{FungibleToken.Receiver}>(/public/fusdReceiver) - .check() - let balance = getAccount(address) - .getCapability<&FUSD.Vault{FungibleToken.Balance}>(/public/fusdBalance) - .check() - return receiver && balance -} diff --git a/cadence/scripts/getFUSDBalance.cdc b/cadence/scripts/getFUSDBalance.cdc deleted file mode 100644 index 99778a9..0000000 --- a/cadence/scripts/getFUSDBalance.cdc +++ /dev/null @@ -1,7 +0,0 @@ -import FungibleToken from 0xFUNGIBLETOKENADDRESS - -pub fun main(addr: Address): UFix64 { - return getAccount(addr) - .getCapability<&{FungibleToken.Balance}>(/public/fusdBalance) - .borrow()?.balance ?? 0.0 -} diff --git a/cadence/transactions/fundFUSD.cdc b/cadence/transactions/fundFUSD.cdc deleted file mode 100644 index 3c7ddaa..0000000 --- a/cadence/transactions/fundFUSD.cdc +++ /dev/null @@ -1,52 +0,0 @@ -import FUSD from 0xFUSDADDRESS -import FungibleToken from 0xFUNGIBLETOKENADDRESS - -pub fun hasFUSD(_ address: Address): Bool { - let receiver = getAccount(address) - .getCapability<&FUSD.Vault{FungibleToken.Receiver}>(/public/fusdReceiver) - .check() - - let balance = getAccount(address) - .getCapability<&FUSD.Vault{FungibleToken.Balance}>(/public/fusdBalance) - .check() - - return receiver && balance -} - -pub fun initFUSD(_ acct: AuthAccount) { - if acct.borrow<&FUSD.Vault>(from: /storage/fusdVault) == nil { - acct.save(<-FUSD.createEmptyVault(), to: /storage/fusdVault) - } - acct.unlink(/public/fusdReceiver) - acct.unlink(/public/fusdBalance) - acct.link<&FUSD.Vault{FungibleToken.Receiver}>(/public/fusdReceiver, target: /storage/fusdVault) - acct.link<&FUSD.Vault{FungibleToken.Balance}>(/public/fusdBalance, target: /storage/fusdVault) -} - -transaction(address: Address, amount: UFix64) { - let tokenAdmin: &FUSD.Administrator - let tokenReceiver: &{FungibleToken.Receiver} - - prepare(minterAccount: AuthAccount, receiverAccount: AuthAccount) { - if !hasFUSD(receiverAccount.address) { - initFUSD(receiverAccount) - } - - self.tokenAdmin = minterAccount - .borrow<&FUSD.Administrator>(from: FUSD.AdminStoragePath) - ?? panic("minterAccount is not the token admin") - - self.tokenReceiver = getAccount(address) - .getCapability(/public/fusdReceiver)! - .borrow<&{FungibleToken.Receiver}>() - ?? panic("Unable to borrow receiver reference") - } - - execute { - let minter <- self.tokenAdmin.createNewMinter() - let mintedVault <- minter.mintTokens(amount: amount) - - self.tokenReceiver.deposit(from: <-mintedVault) - destroy minter - } -} diff --git a/components/AccountBalances.tsx b/components/AccountBalances.tsx index 2168c35..84378ad 100644 --- a/components/AccountBalances.tsx +++ b/components/AccountBalances.tsx @@ -1,10 +1,9 @@ /** @jsxImportSource theme-ui */ import * as fcl from "@onflow/fcl" import useAccount from "hooks/useAccount" -import useFUSDBalance from "hooks/useFUSDBalance" import {fundAccount} from "src/accounts" import {formattedBalance} from "src/balance" -import {FLOW_TYPE, FUSD_TYPE, TokenTypes} from "src/constants" +import {FLOW_TYPE, TokenTypes} from "src/constants" import useConfig from "hooks/useConfig" import {Label, Themed} from "theme-ui" import {SXStyles} from "types" @@ -42,7 +41,6 @@ export default function AccountBalances({ address: string flowAccountAddress: string }) { - const {data: fusdBalance, refresh: refreshFUSD} = useFUSDBalance(address) const {data: account, refresh: refreshAccount} = useAccount(address) const config = useConfig() @@ -52,7 +50,6 @@ export default function AccountBalances({ const fund = async (token: TokenTypes) => { await fundAccount(config, address, token) refreshAccount() - refreshFUSD() } return ( @@ -76,23 +73,6 @@ export default function AccountBalances({ )} -
- -
- {fusdBalance && formattedBalance(fusdBalance.toString())} -
- {!isServiceAccount && ( - - )} -
) } diff --git a/contexts/ConfigContext.tsx b/contexts/ConfigContext.tsx index edcc006..09034ce 100644 --- a/contexts/ConfigContext.tsx +++ b/contexts/ConfigContext.tsx @@ -7,7 +7,6 @@ interface RuntimeConfig { flowAvatarUrl: string contractFungibleToken: string contractFlowToken: string - contractFUSD: string contractFCLCrypto: string flowAccountAddress: string flowAccountPrivateKey: string @@ -22,7 +21,6 @@ const defaultConfig = { flowAvatarUrl: process.env.flowAvatarUrl || "", contractFungibleToken: process.env.contractFungibleToken || "", contractFlowToken: process.env.contractFlowToken || "", - contractFUSD: process.env.contractFUSD || "", contractFCLCrypto: process.env.contractFCLCrypto || "", flowAccountAddress: process.env.flowAccountAddress || "", flowAccountPrivateKey: process.env.flowAccountPrivateKey || "", diff --git a/flow.json b/flow.json index 7f1077c..4b833a4 100755 --- a/flow.json +++ b/flow.json @@ -12,10 +12,6 @@ "emulator": "0xf8d6e0586b0a20c7" } }, - "FUSD": { - "source": "./cadence/contracts/FUSD.cdc", - "aliases": {} - }, "FCLCrypto": { "source": "./cadence/contracts/FCLCrypto.cdc", "aliases": {} @@ -67,10 +63,5 @@ "address": "f8d6e0586b0a20c7", "key": "f8e188e8af0b8b414be59c4a1a15cc666c898fb34d94156e9b51e18bfde754a5" } - }, - "deployments": { - "emulator": { - "emulator-account": ["FUSD"] - } } } diff --git a/go/wallet/.env.development b/go/wallet/.env.development index c8f8ad1..a0cf664 100644 --- a/go/wallet/.env.development +++ b/go/wallet/.env.development @@ -5,7 +5,6 @@ FLOW_INIT_ACCOUNTS=0 CONTRACT_FUNGIBLE_TOKEN=0xee82856bf20e2aa6 CONTRACT_FLOW_TOKEN=0x0ae53cb6e3f42a79 -CONTRACT_FUSD=0xf8d6e0586b0a20c7 CONTRACT_FCL_CRYPTO=0xf8d6e0586b0a20c7 FLOW_AVATAR_URL=https://avatars.onflow.org/avatar/ diff --git a/hooks/useFUSDBalance.ts b/hooks/useFUSDBalance.ts deleted file mode 100644 index 9fa1b67..0000000 --- a/hooks/useFUSDBalance.ts +++ /dev/null @@ -1,40 +0,0 @@ -import {useCallback, useEffect, useState} from "react" -import {getAccountFUSDBalance} from "src/accounts" - -export function compFUSDBalanceKey(address: string) { - return `${address}/fusd-balance` -} - -export function expandFUSDBalanceKey(key: string) { - return { - address: key.split("/")[0], - } -} - -export default function useFUSDBalance(address: string) { - const [balance, setBalance] = useState(null) - const [error, setError] = useState(null) - const [isLoading, setIsLoading] = useState(true) - - const fetchFUSDBalance = useCallback(() => { - getAccountFUSDBalance(address) - .then(balance => { - setBalance(balance) - }) - .catch(error => { - setError(error) - }) - .finally(() => setIsLoading(false)) - }, [address]) - - useEffect(() => { - fetchFUSDBalance() - }, [fetchFUSDBalance]) - - return { - data: balance, - error: error, - isLoading: isLoading, - refresh: fetchFUSDBalance, - } -} diff --git a/next.config.js b/next.config.js index 6f4ce1c..2bf17a1 100644 --- a/next.config.js +++ b/next.config.js @@ -47,7 +47,6 @@ module.exports = { flowAvatarUrl: process.env.FLOW_AVATAR_URL, contractFungibleToken: process.env.CONTRACT_FUNGIBLE_TOKEN, contractFlowToken: process.env.CONTRACT_FLOW_TOKEN, - contractFUSD: process.env.CONTRACT_FUSD, contractFCLCrypto: process.env.CONTRACT_FCL_CRYPTO, }, } diff --git a/src/accounts.ts b/src/accounts.ts index 7ae3949..b76623c 100644 --- a/src/accounts.ts +++ b/src/accounts.ts @@ -4,16 +4,14 @@ import {Optional} from "types" import getAccountsScript from "cadence/scripts/getAccounts.cdc" import getAccountScript from "cadence/scripts/getAccount.cdc" -import getFUSDBalanceScript from "cadence/scripts/getFUSDBalance.cdc" import newAccountTransaction from "cadence/transactions/newAccount.cdc" import updateAccountTransaction from "cadence/transactions/updateAccount.cdc" import fundAccountFLOWTransaction from "cadence/transactions/fundFLOW.cdc" -import fundAccountFUSDTransaction from "cadence/transactions/fundFUSD.cdc" import {authz} from "src/authz" import {FLOW_EVENT_TYPES} from "src/constants" -import {FLOW_TYPE, FUSD_TYPE, TokenType, TokenTypes} from "src/constants" +import {FLOW_TYPE, TokenType, TokenTypes} from "src/constants" export type Account = { type: "ACCOUNT" @@ -159,7 +157,6 @@ type Tokens = Record export const TOKEN_FUNDING_AMOUNTS: Record = { FLOW: "100.0", - FUSD: "100.0", } export const tokens: Tokens = { @@ -167,10 +164,6 @@ export const tokens: Tokens = { tx: fundAccountFLOWTransaction, amount: TOKEN_FUNDING_AMOUNTS[FLOW_TYPE], }, - FUSD: { - tx: fundAccountFUSDTransaction, - amount: TOKEN_FUNDING_AMOUNTS[FUSD_TYPE], - }, } export async function fundAccount( @@ -184,7 +177,7 @@ export async function fundAccount( ) { const {flowAccountAddress, flowAccountKeyId, flowAccountPrivateKey} = config - if (!["FUSD", "FLOW"].includes(token)) { + if (!["FLOW"].includes(token)) { throw "Incorrect TokenType" } @@ -194,16 +187,9 @@ export async function fundAccount( flowAccountPrivateKey ) - const acctAuthz = await authz( - address, - flowAccountKeyId, - flowAccountPrivateKey - ) - const {tx, amount} = tokens[token] - const authorizations = - token === FUSD_TYPE ? [minterAuthz, acctAuthz] : [minterAuthz] + const authorizations = [minterAuthz] const txId = await fcl .send([ @@ -218,14 +204,3 @@ export async function fundAccount( await fcl.tx(txId).onceSealed() } - -export async function getAccountFUSDBalance(address: string): Promise { - const balance = await fcl - .send([ - fcl.script(getFUSDBalanceScript), - fcl.args([fcl.arg(address, t.Address)]), - ]) - .then(fcl.decode) - - return balance -} diff --git a/src/constants.ts b/src/constants.ts index 38d0d2f..3f6f315 100644 --- a/src/constants.ts +++ b/src/constants.ts @@ -7,7 +7,6 @@ export const SERVICE_ACCOUNT_LABEL = "Service Account" export const UNTITLED_APP_NAME = "Untitled Dapp" export const FLOW_TYPE = "FLOW" -export const FUSD_TYPE = "FUSD" -export type TokenTypes = typeof FLOW_TYPE | typeof FUSD_TYPE -export type TokenType = "FLOW" | "FUSD" +export type TokenTypes = typeof FLOW_TYPE +export type TokenType = "FLOW"