Documentation

Version 1.2 - December 2024

Introduction

Welcome to the official documentation for the FileTrust Token. FileTrust represents a groundbreaking approach to secure, decentralized file storage and management. By leveraging Ethereum smart contracts, IPFS, and state-of-the-art encryption methods, FileTrust ensures data integrity, confidentiality, and availability while promoting a fully democratic governance model for its community.

Key Features of FileTrust Token:

  • ERC20-Compliant Token: FileTrust operates on the FTU token, a standard ERC20 token with a fixed total supply of 5,000,000,000 FTU, enabling seamless integration within the blockchain ecosystem.
  • Incentives for Participation: The ecosystem incentivizes Vault Keepers, Guardians, and Contributors for their roles in maintaining the integrity and efficiency of the decentralized file storage system.
  • Democratic Governance: FileTrust empowers token holders through transparent and democratic decision-making. Proposals such as adjusting voting periods, updating quorum percentages, and initiating token burns are determined via token-weighted votes.
  • Community-Controlled Ownership: The contract supports RenounceOwnership and TransferOwnership proposals, ensuring no single entity retains control and fostering a truly decentralized environment.
  • Flexible Governance:
    • Pause/Unpause functionality managed via community votes for handling critical issues.
    • Adjustable Voting Period and Quorum Percentage to accommodate evolving governance needs.
  • Spam Prevention: Proposals require locked fees in FTU tokens, which are refundable upon execution or rejection, ensuring accountability and preventing spam.
  • Transparent Payments and Refunds: Proposal fees are locked during voting and refunded post-execution or rejection, maintaining fairness and encouraging active participation.
  • Token Burn: Community-driven token burn proposals allow for dynamic adjustments to the total supply, ensuring adaptability within the ecosystem.

By incorporating these features, FileTrust ensures a robust and fair ecosystem for secure file storage and decentralized collaboration. Token-weighted voting provides fair representation, while the ability to renounce or transfer ownership establishes trust and autonomy within the community.

Note: This document covers only the main FTU smart contract. In the next phase, we will include documentation for all related smart contracts within the FileTrust project.

For more information, please explore the following resources:

Gas Usage Details

Gas Usage Details

#MethodEstimated Gas UsageRemarks
1Transfer~ 54,555Gas for token transfer
2Approve~ 27,131Approval for token spending
3Propose~ 185,759 ➔ ~ 257,000Depends on proposal complexity
4Vote~ 76,285Voting on a proposal
5Execute Proposal~ 70,742 - 89,832Gas depends on proposal actions
6Cancel Proposal~ 85,000Gas for Cancel Proposal (includes a half penalty)

Propose Function Parameters

This guide explains the parameters for the propose function in the FileTrust Token smart contract.

1. type (Proposal Type)

Value Enum Name Description
0QuorumChange the quorum percentage for proposals.
1VotingPeriodChange the voting period duration.
2PausePause the contract.
3BurnBurn a specific amount of tokens.
4RenounceOwnershipRenounce the ownership of the contract.
5TransferOwnershipTransfer ownership to a new address.
6ProposalFeeChange the fee for creating proposals.

2. parameter (Proposal-Specific Value)

Type (Enum) Example Values Description
Quorum (0)10, 15New quorum percentage (1-100).
VotingPeriod (1)3600New voting period duration in seconds.
Burn (3)500Amount of tokens to burn.
Others0Set to 0 if not applicable.

3. pauseState (Boolean)

Used only for pause-related proposals. For other types, set to false.

  • true: Pause the contract.
  • false: Unpause the contract or not used.

4. proposedOwner (Address)

Used only for ownership-related proposals. For other types, use "0x0000000000000000000000000000000000000000".

  • TransferOwnership (5): Address of the new owner.
  • Others: Set to the zero address if not applicable.

Example Usage


							// Change Quorum to 20%
							await ftuToken.connect(proposer).propose(0, 20, false, "0x0000000000000000000000000000000000000000");
							
							// Pause the Contract
							await ftuToken.connect(proposer).propose(2, 0, true, "0x0000000000000000000000000000000000000000");
							
							// Burn 500 Tokens
							await ftuToken.connect(proposer).propose(3, 500, false, "0x0000000000000000000000000000000000000000");
							
							// Transfer Ownership to a New Address
							await ftuToken.connect(proposer).propose(5, 0, false, newOwner);
						

Vote Function for Voter

This guide explains how voters interact with the vote function in the FileTrust Token smart contract.

1. Parameters for vote Function

Parameter Type Description
proposalId uint256 The ID of the proposal the voter wants to vote on.
support bool Set to true to vote in favor, or false to vote against.

2. Steps for Voting

  1. Ensure you hold FTU tokens in your wallet.
  2. Call the vote function with the desired proposal ID and your vote (support or against).
  3. Wait for the transaction to complete to finalize your vote.

3. Example Code


							// Voter votes in favor of a proposal with ID 1
							const proposalId = 1; // Replace with the actual proposal ID
							const support = true; // Set to false if voting against
							
							await ftuToken.connect(voter).vote(proposalId, support);
							console.log(`Voted ${support ? 'in favor' : 'against'} proposal ID: ${proposalId}`);
						

Load Environment


						// Load environment variables
						require("dotenv").config();
						
						// Import required libraries
						const { ethers } = require("ethers");
						const FTUTokenArtifact = require("./FTUToken.json"); // Adjust the path if necessary
						
						// Initialize provider and wallets
						const provider = new ethers.JsonRpcProvider(process.env.MAINNET_RPC_URL);
						const voter = new ethers.Wallet(process.env.VOTER_PRIVATE_KEY, provider);
						const proposer = new ethers.Wallet(process.env.PROPOSER_PRIVATE_KEY, provider);
						
						// Attach to the deployed contract
						const ftuToken = new ethers.Contract(
						process.env.FTU_TOKEN_ADDRESS, // Fetch contract address from .env
						FTUTokenArtifact.abi,
						voter
						);
						
						console.log("FTUToken attached at:", ftuToken.target);
					

Pause Proposal

Approve

Approve the proposal fee by using the following code:


							const proposalFee = ethers.parseUnits("100", 18); // Proposal fee
							await ftuToken.connect(proposer).approve(ftuToken.target, proposalFee);
						

Note: Ensure the proposer has sufficient FTU tokens to cover the proposal fee.

Create

Create the pause proposal using this code:


							const pauseProposalTx = await ftuToken.connect(proposer).propose(2, 0, true, ethers.ZeroAddress);
							await pauseProposalTx.wait();
						

Point: Proposal type 2 with true indicates a request to pause the contract.

Vote

Vote on the proposal:


							const pauseProposalId = await ftuToken.getProposalsCount();
							await ftuToken.connect(voter).vote(pauseProposalId, true); //true for agree, false for disagree
						

Note: Ensure the voter has not already voted on this proposal to avoid errors.

Result

Execute the proposal and check the result:


							await ftuToken.executeProposal(pauseProposalId);
							console.log("Pause State:", await ftuToken.paused());
						

Point: A successful execution will pause the contract, and the paused() function will return true.

Unpause Proposal

Approve

Approve the proposal fee by using the following code:


								const proposalFee = ethers.parseUnits("100", 18); // Proposal fee
								await ftuToken.connect(proposer).approve(ftuToken.target, proposalFee);
							

Note: Ensure the proposer has sufficient FTU tokens to cover the proposal fee.

Create

Create the unpause proposal using this code:


								const unpauseProposalTx = await ftuToken.connect(proposer).propose(2, 0, false, ethers.ZeroAddress);
								await unpauseProposalTx.wait();
							

Point: Proposal type 2 with false indicates a request to unpause the contract.

Vote

Vote on the proposal:


								const unpauseProposalId = await ftuToken.getProposalsCount();
								await ftuToken.connect(voter).vote(unpauseProposalId, true);
							

Note: Ensure the voter has not already voted on this proposal to avoid errors.

Result

Execute the proposal and check the result:


								await ftuToken.executeProposal(unpauseProposalId);
								console.log("Pause State:", await ftuToken.paused());
							

Point: A successful execution will unpause the contract, and the paused() function will return false.

Burn Proposal

Approve

Approve the proposal fee by using the following code:


							const proposalFee = ethers.parseUnits("100", 18); // Proposal fee
							await ftuToken.connect(proposer).approve(ftuToken.target, proposalFee);
						

Note: Ensure the proposer has sufficient FTU tokens to cover the proposal fee.

Create

Create the burn proposal using this code:


							const burnAmount = ethers.parseUnits("100000", 18);
							const proposeTx = await ftuToken.connect(proposer).propose(3, burnAmount, false, ethers.ZeroAddress);
							await proposeTx.wait();
						

Point: Proposal type 3 indicates a burn proposal, and the burnAmount specifies the number of tokens to be burned.

Vote

Vote on the proposal:


							const burnProposalId = await ftuToken.getProposalsCount();
							await ftuToken.connect(voter).vote(burnProposalId, false);
						

Note: The vote cast here is false, which indicates voting against the proposal. Modify as needed based on the intended outcome.

Result

Execute the proposal and check the result:


							await ftuToken.executeProposal(burnProposalId);
							console.log("Final Total Supply:", (await ftuToken.totalSupply()).toString());
						

Point: After successful execution, the specified burnAmount will be deducted from the total supply, and the new total supply can be verified.

Quorum Proposal

Approve

Approve the proposal fee by using the following code:


							const proposalFee = ethers.parseUnits("100", 18); // Proposal fee
							await ftuToken.connect(proposer).approve(ftuToken.target, proposalFee);
						

Note: Ensure the proposer has sufficient FTU tokens to cover the proposal fee.

Create

Create the quorum proposal using this code:


							const newQuorum = 15; // New quorum percentage
							const quorumProposalTx = await ftuToken.connect(proposer).propose(0, newQuorum, false, ethers.ZeroAddress);
							await quorumProposalTx.wait();
						

Point: Proposal type 0 is used for updating the quorum percentage.

Vote

Vote on the proposal:


							const quorumProposalId = await ftuToken.getProposalsCount();
							await ftuToken.connect(voter).vote(quorumProposalId, true);
						

Note: The vote cast here is true, indicating support for the proposal.

Result

Execute the proposal and check the result:


							await ftuToken.executeProposal(quorumProposalId);
							console.log("Quorum Percentage:", (await ftuToken.currentQuorumPercentage()).toString());
						

Point: After successful execution, the quorum percentage will be updated to the new value, and the result can be verified using the currentQuorumPercentage function.

Fee Change Proposal

Approve

Approve the proposal fee by using the following code:


							const proposalFee = ethers.parseUnits("100", 18); // Proposal fee
							await ftuToken.connect(proposer).approve(ftuToken.target, proposalFee);
						

Note: Ensure the proposer has sufficient FTU tokens to cover the proposal fee.

Create

Create the fee change proposal using this code:


							const newProposalFee = ethers.parseUnits("150", 18); // New proposal fee amount
							const proposalFeeProposalTx = await ftuToken.connect(proposer).propose(6, newProposalFee, false, ethers.ZeroAddress);
							await proposalFeeProposalTx.wait();
						

Point: Proposal type 6 is used for updating the proposal fee value.

Vote

Vote on the proposal:


							const proposalFeeProposalId = await ftuToken.getProposalsCount();
							await ftuToken.connect(voter).vote(proposalFeeProposalId, true);
						

Note: The vote cast here is true, indicating support for the proposal.

Result

Execute the proposal and check the result:


							await ftuToken.executeProposal(proposalFeeProposalId);
							console.log("Updated Proposal Fee:", (await ftuToken.proposalFee()).toString());
						

Point: After successful execution, the proposal fee will be updated to the new value, and the result can be verified using the proposalFee function.

Voting Period Change Proposal

Approve

Approve the proposal fee by using the following code:


							const proposalFee = ethers.parseUnits("100", 18); // Proposal fee
							await ftuToken.connect(proposer).approve(ftuToken.target, proposalFee);
						

Note: Ensure the proposer has sufficient FTU tokens to cover the proposal fee.

Create

Create the voting period change proposal using this code:


							const newVotingPeriod = 5 * 60; // New voting period in seconds
							const votingPeriodProposalTx = await ftuToken.connect(proposer).propose(1, newVotingPeriod, false, ethers.ZeroAddress);
							await votingPeriodProposalTx.wait();
						

Point: Proposal type 1 is used for updating the voting period duration.

Vote

Vote on the proposal:


							const votingPeriodProposalId = await ftuToken.getProposalsCount();
							await ftuToken.connect(voter).vote(votingPeriodProposalId, true);
						

Note: The vote cast here is true, indicating support for the proposal.

Result

Execute the proposal and check the result:


							await ftuToken.executeProposal(votingPeriodProposalId);
							console.log("Voting Period:", (await ftuToken.currentVotingPeriod()).toString(), "seconds");
						

Point: After successful execution, the voting period will be updated to the new value, and the result can be verified using the currentVotingPeriod function.

Transfer Ownership Proposal

Approve

Approve the proposal fee by using the following code:


							const proposalFee = ethers.parseUnits("100", 18); // Proposal fee
							await ftuToken.connect(proposer).approve(ftuToken.target, proposalFee);
							console.log("Proposal fee approved by proposer");
						

Note: Ensure the proposer has sufficient FTU tokens to cover the proposal fee.

Create

Create the transfer ownership proposal using this code:


							const newOwner = "0xNewOwnerAddressHere"; // Replace with the actual new owner's address
							const transferOwnershipProposalTx = await ftuToken.connect(proposer).propose(
							4, // ProposalType.TransferOwnership
							0, // No parameter needed for ownership transfer
							false, // Pause state not relevant for this proposal
							newOwner // The proposed new owner address
							);
							await transferOwnershipProposalTx.wait();
							console.log("Transfer ownership proposal created");
						

Point: Proposal type 4 is used for transferring ownership of the contract to a new owner.

Vote

Vote on the proposal:


							const transferOwnershipProposalId = await ftuToken.getProposalsCount();
							await ftuToken.connect(voter).vote(transferOwnershipProposalId, true); // Voter votes in favor
							console.log("Voter voted in favor of the transfer ownership proposal");
						

Note: The vote cast here is true, indicating support for the proposal.

Result

Execute the proposal and check the result:


							await ftuToken.executeProposal(transferOwnershipProposalId);
							console.log("Transfer ownership proposal executed");
							const updatedOwner = await ftuToken.owner();
							console.log("New Owner after transfer:", updatedOwner);
						

Point: After successful execution, the contract ownership will be transferred to the new owner address specified in the proposal.

Renounce Ownership Proposal

Approve

Approve the proposal fee by using the following code:


							const proposalFee = ethers.parseUnits("100", 18); // Proposal fee
							await ftuToken.connect(proposer).approve(ftuToken.target, proposalFee);
							console.log("Proposal fee approved by proposer");
						

Note: Ensure the proposer has sufficient FTU tokens to cover the proposal fee.

Create

Create the renounce ownership proposal using this code:


							const renounceOwnershipProposalTx = await ftuToken.connect(proposer).propose(
							5, // ProposalType.RenounceOwnership
							0, // No parameter needed for renouncing ownership
							false, // Pause state not relevant for this proposal
							ethers.ZeroAddress // No new owner is proposed
							);
							await renounceOwnershipProposalTx.wait();
							console.log("Renounce ownership proposal created");
						

Point: Proposal type 5 is used for renouncing ownership, ensuring no new owner is assigned.

Vote

Vote on the proposal:


							const renounceOwnershipProposalId = await ftuToken.getProposalsCount();
							await ftuToken.connect(voter).vote(renounceOwnershipProposalId, true); // Voter votes in favor
							console.log("Voter voted in favor of the renounce ownership proposal");
						

Note: The vote cast here is true, indicating support for the proposal.

Result

Execute the proposal and check the result:


							await ftuToken.executeProposal(renounceOwnershipProposalId);
							console.log("Renounce ownership proposal executed");
							const ownerAfterRenounce = await ftuToken.owner();
							console.log("Owner after renounce:", ownerAfterRenounce);
						

Point: After successful execution, the contract ownership will be renounced, and the owner address will be set to 0x0.

Check Status

							
								console.log("Status of All Settings:");
								
								// Check current quorum percentage
								console.log("Quorum Percentage:", (await ftuToken.currentQuorumPercentage()).toString());
								// Comment: Retrieves the percentage of votes required for a proposal to pass.
								
								// Check current voting period duration
								console.log("Voting Period:", (await ftuToken.currentVotingPeriod()).toString(), "seconds");
								// Comment: Retrieves the duration (in seconds) allocated for voting on proposals.
								
								// Check if the contract is currently paused
								console.log("Pause State:", await ftuToken.paused());
								// Comment: Indicates whether the contract is in a paused state.
								
								// Check the total token supply
								console.log("Total Supply:", (await ftuToken.totalSupply()).toString());
								// Comment: Retrieves the current total supply of tokens.
								
								// Check the proposal fee
								console.log("Proposal Fee:", (await ftuToken.proposalFee()).toString());
								// Comment: Retrieves the fee required to create a new proposal.
								
								// Check the current owner of the contract
								const currentOwner = await ftuToken.owner();
								console.log("Current Owner:", currentOwner);
								// Comment: Retrieves the address of the current owner of the contract.
							
						

Cancel Proposal

This guide explains how proposers can cancel a proposal using the cancelProposal function in the FileTrust Token smart contract.

1. Parameters for cancelProposal Function

Parameter Type Description
proposalId uint256 The ID of the proposal to be canceled.

2. Steps for Canceling a Proposal

  1. Retrieve the most recent proposal ID using the getProposalsCount function.
  2. Call the cancelProposal function with the retrieved proposal ID.
  3. Wait for the transaction to complete. Half of the proposal fee will be refunded upon successful cancellation.
Note: After the voting period has ended, it is no longer possible to cancel a proposal.

3. Example Code


							// Get the most recent proposal ID
							const proposalId = await ftuToken.getProposalsCount();
							console.log("Proposal ID:", proposalId.toString());
							
							// Cancel the proposal
							const cancelTx = await ftuToken.connect(proposer).cancelProposal(proposalId);
							await cancelTx.wait();
							console.log("Proposal canceled successfully and half of the fee refunded.");