Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 22 additions & 0 deletions transactions/withdraw-fraudulent-tokens/feb-23/README.md
Original file line number Diff line number Diff line change
@@ -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: 1dbba95678f7b61e392cb4ed3f528f187fd7c34ac749daaa01864dcc3bcfa403
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import FungibleToken from 0xf233dcee88fe0abe
import RetrieveFraudulentTokensEvents from 0xe467b9dd11fa00df

/// 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 {

prepare(serviceAccount: auth(Storage, Capabilities, BorrowValue) &Account) {

// the amount to burn
let amount = 50343896.87728200

let defaultFlowTokenVaultPath = /storage/flowTokenVault

// Get a reference to the service account's default flow vault
let serviceAccountDefaultVaultRef = serviceAccount.storage.borrow<auth(FungibleToken.Withdraw) &{FungibleToken.Vault}>(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)")

eventAdmin.emitRetrieveTokensEvent(typeIdentifier: serviceAccountDefaultVaultRef.getType().identifier, amount: amount, fromAddress: serviceAccount.address.toString())

eventAdmin.emitDestroyTokensEvent(typeIdentifier: vault.getType().identifier, amount: vault.balance)

// Destroy the tokens
destroy <-vault

}
}
36 changes: 36 additions & 0 deletions transactions/withdraw-fraudulent-tokens/feb-23/test_script.cdc
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
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 = 50344317.76
let serviceAccount = getAuthAccount<auth(Storage, Capabilities, BorrowValue) &Account>(authorizer)

let defaultFlowTokenVaultPath = /storage/flowTokenVault

// Get a reference to the service account's default flow vault
let serviceAccountDefaultVaultRef = serviceAccount.storage.borrow<auth(FungibleToken.Withdraw) &{FungibleToken.Vault}>(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)")

eventAdmin.emitRetrieveTokensEvent(typeIdentifier: serviceAccountDefaultVaultRef.getType().identifier, amount: amount, fromAddress: serviceAccount.address.toString())

eventAdmin.emitDestroyTokensEvent(typeIdentifier: vault.getType().identifier, amount: vault.balance)

// Destroy the tokens
destroy <-vault

}