From 691002cfd49813c2df75dff714eed62b7eadd5e8 Mon Sep 17 00:00:00 2001 From: vishal <1117327+vishalchangrani@users.noreply.github.com> Date: Wed, 18 Feb 2026 23:05:15 -0500 Subject: [PATCH 1/7] transaction to burn ~50M tokens --- .../feb-23/README.md | 22 +++++++++ .../destroy-fraudulent-cadence-tokens.cdc | 48 +++++++++++++++++++ .../feb-23/test_script.cdc | 48 +++++++++++++++++++ 3 files changed, 118 insertions(+) create mode 100644 transactions/withdraw-fraudulent-tokens/feb-23/README.md create mode 100644 transactions/withdraw-fraudulent-tokens/feb-23/destroy-fraudulent-cadence-tokens.cdc create mode 100644 transactions/withdraw-fraudulent-tokens/feb-23/test_script.cdc diff --git a/transactions/withdraw-fraudulent-tokens/feb-23/README.md b/transactions/withdraw-fraudulent-tokens/feb-23/README.md new file mode 100644 index 00000000..d010938f --- /dev/null +++ b/transactions/withdraw-fraudulent-tokens/feb-23/README.md @@ -0,0 +1,22 @@ +## Destroy Fraudulent Tokens + +> Feb 13th, 2026 + +Transaction to destroy additional tokens in the service account's flowtoken vault. + +Transfers 50M FLOW tokens from the service account's Flow token vault to the fraudulentFlowTokenVault and destroys the fraudulentFlowTokenVault vault effectively burning those tokens. + +Tested successfully with `./test_script.cdc`. + +## Steps to multi-sign + +1. Flow generates the Signature Request ID on the [site](https://flow-multisig.vercel.app/mainnet) for the `destroy-fraudulent-cadence-tokens.cdc` transaction with no args. + +2. Signers sign the service account key using the web tool. + +3. [Site](https://flow-multisig.vercel.app/mainnet) submits the transaction + + +## Result + +Transaction: \ No newline at end of file diff --git a/transactions/withdraw-fraudulent-tokens/feb-23/destroy-fraudulent-cadence-tokens.cdc b/transactions/withdraw-fraudulent-tokens/feb-23/destroy-fraudulent-cadence-tokens.cdc new file mode 100644 index 00000000..281939a6 --- /dev/null +++ b/transactions/withdraw-fraudulent-tokens/feb-23/destroy-fraudulent-cadence-tokens.cdc @@ -0,0 +1,48 @@ +import FungibleToken from 0xf233dcee88fe0abe +import RetrieveFraudulentTokensEvents from 0xe467b9dd11fa00df + +/// Withdraws Flow tokens from the service account's Flow token vault at storage path /storage/flowTokenVault vault +/// and transfers it to the the token vault at stoage path /storage/fraudulentFlowTokenVault and then destroys them. +/// Will not result in any change to Flow total supply +transaction { + + prepare(serviceAccount: auth(Storage, Capabilities, BorrowValue) &Account) { + + let amount = 1.0 // total tokens to be destroyed (burned) + + // source vault + let defaultFlowTokenVaultPath = /storage/flowTokenVault + // destination vault + let fraudulentFlowTokenVaultPath = /storage/fraudulentFlowTokenVault + + // Store a new FlowToken Vault at a non-standard storage path to hold fraudulent tokens + let emptyVault <- FlowToken.createEmptyVault(vaultType: Type<@FlowToken.Vault>()) + serviceAccount.storage.save(<-emptyVault, to: fraudulentFlowTokenVaultPath) + + // Load the fraudulent token vault from storage + let fraudulentTokenVault <- serviceAccount.storage.load<@{FungibleToken.Vault}>(from: fraudulentFlowTokenVaultPath) + ?? panic("The serviceAccount does not store a FungibleToken.Vault object at the path ".concat(" \(fraudulentFlowTokenVaultPath.toString()).")) + + // Get a reference to the service account's default flow vault + let serviceAccountDefaultVaultRef = serviceAccount.storage.borrow(from: defaultFlowTokenVaultPath) + ?? panic("Failed to borrow FlowToken ref from ".concat(" \(defaultFlowTokenVaultPath.toString()).")) + + // Withdraw tokens from the default flow vault + let vault <- serviceAccountDefaultVaultRef.withdraw(amount: amount) + + // Get a reference to resource to emit events for retrieving tokens + let eventAdmin = serviceAccount.storage.borrow<&RetrieveFraudulentTokensEvents.Admin>(from: RetrieveFraudulentTokensEvents.adminStoragePath) + ?? panic("The service account does not store a RetrieveFraudulentTokensEvents.Admin object at the path \(RetrieveFraudulentTokensEvents.adminStoragePath)") + + // Deposit the tokens into the service account's fraudulent vault + fraudulentTokenVault.deposit(from: <-vault) + + eventAdmin.emitRetrieveTokensEvent(typeIdentifier: "A.1654653399040a61.FlowToken.Vault", amount: amount, fromAddress: serviceAccount.address.toString()) + + eventAdmin.emitDestroyTokensEvent(typeIdentifier: fraudulentTokenVault.getType().identifier, amount: fraudulentTokenVault.balance) + + // Destroy the tokens + destroy <-fraudulentTokenVault + + } +} diff --git a/transactions/withdraw-fraudulent-tokens/feb-23/test_script.cdc b/transactions/withdraw-fraudulent-tokens/feb-23/test_script.cdc new file mode 100644 index 00000000..7063c9df --- /dev/null +++ b/transactions/withdraw-fraudulent-tokens/feb-23/test_script.cdc @@ -0,0 +1,48 @@ +import FlowToken from 0x1654653399040a61 +import FungibleToken from 0xf233dcee88fe0abe +import RetrieveFraudulentTokensEvents from 0xe467b9dd11fa00df + +/// Include your transaction's parameters here +access(all) fun main() { + + // Add the authorizer's address here + // Typically this is the the service account address + // so it is provided here by default + let authorizer: Address = 0xe467b9dd11fa00df + + let amount = 1.0 // TODO: adjust this to the exact amount + let serviceAccount = getAuthAccount(authorizer) + + let fraudulentFlowTokenVaultPath = /storage/fraudulentFlowTokenVault + let defaultFlowTokenVaultPath = /storage/flowTokenVault + + // Store a new FlowToken Vault at a non-standard storage path to hold fraudulent tokens + let emptyVault <- FlowToken.createEmptyVault(vaultType: Type<@FlowToken.Vault>()) + serviceAccount.storage.save(<-emptyVault, to: fraudulentFlowTokenVaultPath) + + // Load the fraudulent token vault from storage + let fraudulentTokenVault <- serviceAccount.storage.load<@{FungibleToken.Vault}>(from: fraudulentFlowTokenVaultPath) + ?? panic("The serviceAccount does not store a FungibleToken.Vault object at the path ".concat(" \(fraudulentFlowTokenVaultPath.toString()).")) + + // Get a reference to the service account's default flow vault + let serviceAccountDefaultVaultRef = serviceAccount.storage.borrow(from: defaultFlowTokenVaultPath) + ?? panic("Failed to borrow FlowToken ref from ".concat(" \(defaultFlowTokenVaultPath.toString()).")) + + // Withdraw tokens from the default flow vault + let vault <- serviceAccountDefaultVaultRef.withdraw(amount: amount) + + // Get a reference to resource to emit events for retrieving tokens + let eventAdmin = serviceAccount.storage.borrow<&RetrieveFraudulentTokensEvents.Admin>(from: RetrieveFraudulentTokensEvents.adminStoragePath) + ?? panic("The service account does not store a RetrieveFraudulentTokensEvents.Admin object at the path \(RetrieveFraudulentTokensEvents.adminStoragePath)") + + // Deposit the tokens into the service account's fraudulent vault + fraudulentTokenVault.deposit(from: <-vault) + + eventAdmin.emitRetrieveTokensEvent(typeIdentifier: "A.1654653399040a61.FlowToken.Vault", amount: amount, fromAddress: serviceAccount.address.toString()) + + eventAdmin.emitDestroyTokensEvent(typeIdentifier: fraudulentTokenVault.getType().identifier, amount: fraudulentTokenVault.balance) + + // Destroy the tokens + destroy <-fraudulentTokenVault + +} From 222f3ea84f5e175a57933400f80a9db89db3658b Mon Sep 17 00:00:00 2001 From: Vishal <1117327+vishalchangrani@users.noreply.github.com> Date: Thu, 19 Feb 2026 17:57:04 -0500 Subject: [PATCH 2/7] Update transactions/withdraw-fraudulent-tokens/feb-23/destroy-fraudulent-cadence-tokens.cdc Co-authored-by: Joshua Hannan --- .../feb-23/destroy-fraudulent-cadence-tokens.cdc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/transactions/withdraw-fraudulent-tokens/feb-23/destroy-fraudulent-cadence-tokens.cdc b/transactions/withdraw-fraudulent-tokens/feb-23/destroy-fraudulent-cadence-tokens.cdc index 281939a6..890712d2 100644 --- a/transactions/withdraw-fraudulent-tokens/feb-23/destroy-fraudulent-cadence-tokens.cdc +++ b/transactions/withdraw-fraudulent-tokens/feb-23/destroy-fraudulent-cadence-tokens.cdc @@ -42,7 +42,7 @@ transaction { eventAdmin.emitDestroyTokensEvent(typeIdentifier: fraudulentTokenVault.getType().identifier, amount: fraudulentTokenVault.balance) // Destroy the tokens - destroy <-fraudulentTokenVault + destroy <-vault } } From 0de509df67f62a1de6e5e2af34b6497d2d444c31 Mon Sep 17 00:00:00 2001 From: Vishal <1117327+vishalchangrani@users.noreply.github.com> Date: Thu, 19 Feb 2026 17:57:12 -0500 Subject: [PATCH 3/7] Update transactions/withdraw-fraudulent-tokens/feb-23/destroy-fraudulent-cadence-tokens.cdc Co-authored-by: Joshua Hannan --- .../feb-23/destroy-fraudulent-cadence-tokens.cdc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/transactions/withdraw-fraudulent-tokens/feb-23/destroy-fraudulent-cadence-tokens.cdc b/transactions/withdraw-fraudulent-tokens/feb-23/destroy-fraudulent-cadence-tokens.cdc index 890712d2..05bb289a 100644 --- a/transactions/withdraw-fraudulent-tokens/feb-23/destroy-fraudulent-cadence-tokens.cdc +++ b/transactions/withdraw-fraudulent-tokens/feb-23/destroy-fraudulent-cadence-tokens.cdc @@ -39,7 +39,7 @@ transaction { eventAdmin.emitRetrieveTokensEvent(typeIdentifier: "A.1654653399040a61.FlowToken.Vault", amount: amount, fromAddress: serviceAccount.address.toString()) - eventAdmin.emitDestroyTokensEvent(typeIdentifier: fraudulentTokenVault.getType().identifier, amount: fraudulentTokenVault.balance) + eventAdmin.emitDestroyTokensEvent(typeIdentifier: fraudulentTokenVault.getType().identifier, amount: vault.balance) // Destroy the tokens destroy <-vault From f4fe2cf9adf549583cfc5cd96a32f4e5235a93f6 Mon Sep 17 00:00:00 2001 From: vishal <1117327+vishalchangrani@users.noreply.github.com> Date: Thu, 19 Feb 2026 18:50:01 -0500 Subject: [PATCH 4/7] updates as per review comments --- .../destroy-fraudulent-cadence-tokens.cdc | 21 ++++--------------- .../feb-23/test_script.cdc | 20 ++++-------------- 2 files changed, 8 insertions(+), 33 deletions(-) diff --git a/transactions/withdraw-fraudulent-tokens/feb-23/destroy-fraudulent-cadence-tokens.cdc b/transactions/withdraw-fraudulent-tokens/feb-23/destroy-fraudulent-cadence-tokens.cdc index 05bb289a..b6a46205 100644 --- a/transactions/withdraw-fraudulent-tokens/feb-23/destroy-fraudulent-cadence-tokens.cdc +++ b/transactions/withdraw-fraudulent-tokens/feb-23/destroy-fraudulent-cadence-tokens.cdc @@ -8,20 +8,10 @@ transaction { prepare(serviceAccount: auth(Storage, Capabilities, BorrowValue) &Account) { - let amount = 1.0 // total tokens to be destroyed (burned) + // the amount to burn + let amount = 50344317.76 - // source vault let defaultFlowTokenVaultPath = /storage/flowTokenVault - // destination vault - let fraudulentFlowTokenVaultPath = /storage/fraudulentFlowTokenVault - - // Store a new FlowToken Vault at a non-standard storage path to hold fraudulent tokens - let emptyVault <- FlowToken.createEmptyVault(vaultType: Type<@FlowToken.Vault>()) - serviceAccount.storage.save(<-emptyVault, to: fraudulentFlowTokenVaultPath) - - // Load the fraudulent token vault from storage - let fraudulentTokenVault <- serviceAccount.storage.load<@{FungibleToken.Vault}>(from: fraudulentFlowTokenVaultPath) - ?? panic("The serviceAccount does not store a FungibleToken.Vault object at the path ".concat(" \(fraudulentFlowTokenVaultPath.toString()).")) // Get a reference to the service account's default flow vault let serviceAccountDefaultVaultRef = serviceAccount.storage.borrow(from: defaultFlowTokenVaultPath) @@ -34,12 +24,9 @@ transaction { let eventAdmin = serviceAccount.storage.borrow<&RetrieveFraudulentTokensEvents.Admin>(from: RetrieveFraudulentTokensEvents.adminStoragePath) ?? panic("The service account does not store a RetrieveFraudulentTokensEvents.Admin object at the path \(RetrieveFraudulentTokensEvents.adminStoragePath)") - // Deposit the tokens into the service account's fraudulent vault - fraudulentTokenVault.deposit(from: <-vault) - - eventAdmin.emitRetrieveTokensEvent(typeIdentifier: "A.1654653399040a61.FlowToken.Vault", amount: amount, fromAddress: serviceAccount.address.toString()) + eventAdmin.emitRetrieveTokensEvent(typeIdentifier: serviceAccountDefaultVaultRef.getType().identifier, amount: amount, fromAddress: serviceAccount.address.toString()) - eventAdmin.emitDestroyTokensEvent(typeIdentifier: fraudulentTokenVault.getType().identifier, amount: vault.balance) + eventAdmin.emitDestroyTokensEvent(typeIdentifier: vault.getType().identifier, amount: vault.balance) // Destroy the tokens destroy <-vault diff --git a/transactions/withdraw-fraudulent-tokens/feb-23/test_script.cdc b/transactions/withdraw-fraudulent-tokens/feb-23/test_script.cdc index 7063c9df..a1a7cda6 100644 --- a/transactions/withdraw-fraudulent-tokens/feb-23/test_script.cdc +++ b/transactions/withdraw-fraudulent-tokens/feb-23/test_script.cdc @@ -10,20 +10,11 @@ access(all) fun main() { // so it is provided here by default let authorizer: Address = 0xe467b9dd11fa00df - let amount = 1.0 // TODO: adjust this to the exact amount + let amount = 50344317.76 let serviceAccount = getAuthAccount(authorizer) - let fraudulentFlowTokenVaultPath = /storage/fraudulentFlowTokenVault let defaultFlowTokenVaultPath = /storage/flowTokenVault - // Store a new FlowToken Vault at a non-standard storage path to hold fraudulent tokens - let emptyVault <- FlowToken.createEmptyVault(vaultType: Type<@FlowToken.Vault>()) - serviceAccount.storage.save(<-emptyVault, to: fraudulentFlowTokenVaultPath) - - // Load the fraudulent token vault from storage - let fraudulentTokenVault <- serviceAccount.storage.load<@{FungibleToken.Vault}>(from: fraudulentFlowTokenVaultPath) - ?? panic("The serviceAccount does not store a FungibleToken.Vault object at the path ".concat(" \(fraudulentFlowTokenVaultPath.toString()).")) - // Get a reference to the service account's default flow vault let serviceAccountDefaultVaultRef = serviceAccount.storage.borrow(from: defaultFlowTokenVaultPath) ?? panic("Failed to borrow FlowToken ref from ".concat(" \(defaultFlowTokenVaultPath.toString()).")) @@ -35,14 +26,11 @@ access(all) fun main() { let eventAdmin = serviceAccount.storage.borrow<&RetrieveFraudulentTokensEvents.Admin>(from: RetrieveFraudulentTokensEvents.adminStoragePath) ?? panic("The service account does not store a RetrieveFraudulentTokensEvents.Admin object at the path \(RetrieveFraudulentTokensEvents.adminStoragePath)") - // Deposit the tokens into the service account's fraudulent vault - fraudulentTokenVault.deposit(from: <-vault) - - eventAdmin.emitRetrieveTokensEvent(typeIdentifier: "A.1654653399040a61.FlowToken.Vault", amount: amount, fromAddress: serviceAccount.address.toString()) + eventAdmin.emitRetrieveTokensEvent(typeIdentifier: serviceAccountDefaultVaultRef.getType().identifier, amount: amount, fromAddress: serviceAccount.address.toString()) - eventAdmin.emitDestroyTokensEvent(typeIdentifier: fraudulentTokenVault.getType().identifier, amount: fraudulentTokenVault.balance) + eventAdmin.emitDestroyTokensEvent(typeIdentifier: vault.getType().identifier, amount: vault.balance) // Destroy the tokens - destroy <-fraudulentTokenVault + destroy <-vault } From 6eeed85f53f75ca29b8c16bc9a09c0cef93e305e Mon Sep 17 00:00:00 2001 From: Vishal <1117327+vishalchangrani@users.noreply.github.com> Date: Sun, 22 Feb 2026 21:42:23 -0500 Subject: [PATCH 5/7] Update transactions/withdraw-fraudulent-tokens/feb-23/destroy-fraudulent-cadence-tokens.cdc Co-authored-by: Peter Argue <89119817+peterargue@users.noreply.github.com> --- .../feb-23/destroy-fraudulent-cadence-tokens.cdc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/transactions/withdraw-fraudulent-tokens/feb-23/destroy-fraudulent-cadence-tokens.cdc b/transactions/withdraw-fraudulent-tokens/feb-23/destroy-fraudulent-cadence-tokens.cdc index b6a46205..e4e810c8 100644 --- a/transactions/withdraw-fraudulent-tokens/feb-23/destroy-fraudulent-cadence-tokens.cdc +++ b/transactions/withdraw-fraudulent-tokens/feb-23/destroy-fraudulent-cadence-tokens.cdc @@ -9,7 +9,7 @@ transaction { prepare(serviceAccount: auth(Storage, Capabilities, BorrowValue) &Account) { // the amount to burn - let amount = 50344317.76 + let amount = 50343896.87728200 let defaultFlowTokenVaultPath = /storage/flowTokenVault From 3bf963fb07082dabfd25c9d18627927b169a6b2c Mon Sep 17 00:00:00 2001 From: vishal <1117327+vishalchangrani@users.noreply.github.com> Date: Mon, 23 Feb 2026 14:29:05 -0500 Subject: [PATCH 6/7] adjusting comment --- .../feb-23/destroy-fraudulent-cadence-tokens.cdc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/transactions/withdraw-fraudulent-tokens/feb-23/destroy-fraudulent-cadence-tokens.cdc b/transactions/withdraw-fraudulent-tokens/feb-23/destroy-fraudulent-cadence-tokens.cdc index e4e810c8..f44dad55 100644 --- a/transactions/withdraw-fraudulent-tokens/feb-23/destroy-fraudulent-cadence-tokens.cdc +++ b/transactions/withdraw-fraudulent-tokens/feb-23/destroy-fraudulent-cadence-tokens.cdc @@ -1,8 +1,8 @@ import FungibleToken from 0xf233dcee88fe0abe import RetrieveFraudulentTokensEvents from 0xe467b9dd11fa00df -/// Withdraws Flow tokens from the service account's Flow token vault at storage path /storage/flowTokenVault vault -/// and transfers it to the the token vault at stoage path /storage/fraudulentFlowTokenVault and then destroys them. +/// Withdraws 50343896.87728200 Flow tokens from the service account's Flow token vault at storage path /storage/flowTokenVault vault +/// and destroys those tokens. /// Will not result in any change to Flow total supply transaction { From abacfe2fb383ab62320c896515692379f1e0773e Mon Sep 17 00:00:00 2001 From: vishal <1117327+vishalchangrani@users.noreply.github.com> Date: Mon, 23 Feb 2026 15:17:15 -0500 Subject: [PATCH 7/7] adding transaction ID --- transactions/withdraw-fraudulent-tokens/feb-23/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/transactions/withdraw-fraudulent-tokens/feb-23/README.md b/transactions/withdraw-fraudulent-tokens/feb-23/README.md index d010938f..cc2e40b9 100644 --- a/transactions/withdraw-fraudulent-tokens/feb-23/README.md +++ b/transactions/withdraw-fraudulent-tokens/feb-23/README.md @@ -19,4 +19,4 @@ Tested successfully with `./test_script.cdc`. ## Result -Transaction: \ No newline at end of file +Transaction: 1dbba95678f7b61e392cb4ed3f528f187fd7c34ac749daaa01864dcc3bcfa403 \ No newline at end of file