-
Notifications
You must be signed in to change notification settings - Fork 576
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
2 changed files
with
423 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,203 @@ | ||
--- | ||
eip: 0000 | ||
title: Diffusive Tokens | ||
description: A fungible token that mints new tokens on transfer, charges a per-token native fee, and enforces a capped supply. | ||
author: James Savechives (@jamesavechives) | ||
discussions-to: https://ethereum-magicians.org/t/discussion-on-eip-0000-diffusive-tokens/20890 | ||
status: Draft | ||
type: Standards Track | ||
category: ERC | ||
created: 2024-12-07 | ||
--- | ||
|
||
## Abstract | ||
|
||
This ERC proposes a standard for a new type of fungible token, called **Diffusive Tokens (DIFF)**. Unlike traditional [ERC-20](./eip-20.md) tokens, transferring DIFF tokens does not decrease the sender’s balance. Instead, it *mints* new tokens directly to the recipient, increasing the total supply on every transfer action. A fixed native currency fee is charged per token transferred, and this fee is paid by the sender to the contract owner. The supply growth is limited by a maximum supply set by the owner. Token holders can also burn their tokens to reduce the total supply. These features enable a controlled, incentivized token distribution model that merges fungibility with a built-in economic mechanism. | ||
|
||
## Motivation | ||
|
||
Traditional [ERC-20](./eip-20.md) tokens maintain a constant total supply and simply redistribute balances on transfers. While this model is widespread, certain use cases benefit from a token design that continuously expands supply during transfers, simulating a controlled "diffusion" of value. The Diffusive Token model may be suitable for representing claims on real-world goods (e.g., a product batch like iPhone 15 units), digital goods, or controlled asset distributions where initial token distribution and ongoing availability need to be managed differently. | ||
|
||
This model also includes a native currency fee per token transferred, incentivizing careful, value-driven transfers and providing a revenue stream for the token’s issuer. The maximum supply cap prevents unbounded inflation, ensuring long-term scarcity. The ability for owners to burn tokens to redeem underlying goods or services directly maps on-chain assets to real-world redemptions. | ||
|
||
## Specification | ||
|
||
### Terminology | ||
|
||
- **Diffusive Token**: A fungible token unit that is minted on transfers. | ||
- **Max Supply**: The maximum total supply the token can reach. | ||
- **Transfer Fee**: A fee in native blockchain currency (e.g., ETH) that must be paid by the sender for each token transferred. The total fee = `transferFee * amount`. | ||
- **Burn**: The action of destroying tokens, reducing both the holder’s balance and the total supply. | ||
|
||
### Data Structures | ||
|
||
- **Balances Mapping**: `balances[address] = uint256` tracks the number of tokens owned by each address. | ||
|
||
```solidity | ||
mapping(address => uint256) private balances; | ||
``` | ||
|
||
- **Total Supply and Max Supply**: | ||
|
||
```solidity | ||
uint256 public totalSupply; | ||
uint256 public maxSupply; | ||
``` | ||
|
||
- **Transfer Fee**: | ||
|
||
```solidity | ||
uint256 public transferFee; // fee per token transferred in wei | ||
address public owner; | ||
``` | ||
|
||
The `owner` sets and updates `transferFee` and `maxSupply`. | ||
|
||
### Token Semantics | ||
|
||
1. **Minting on Transfer** | ||
When a transfer occurs from `A` to `B`: | ||
- `A` does not lose any tokens. | ||
- `B` receives newly minted tokens (increasing their balance and totalSupply). | ||
- The `totalSupply` increases by the transferred amount, but must not exceed `maxSupply`. | ||
|
||
2. **Fixed Transfer Fee in Native Currency** | ||
Each transfer requires the sender to pay `transferFee * amount` in the native currency. If `msg.value` is insufficient, the transaction reverts. | ||
|
||
3. **Maximum Supply** | ||
If a transfer would cause `totalSupply + amount > maxSupply`, it must revert. | ||
|
||
4. **Burning Tokens** | ||
Token holders can burn tokens to: | ||
- Reduce their balance by the burned amount. | ||
- Decrease `totalSupply` by the burned amount. | ||
|
||
This can map to redeeming underlying goods or simply deflating the token. | ||
|
||
### Interface | ||
|
||
The DIFF standard aligns partially with [ERC-20](./eip-20.md), but redefines certain behaviors: | ||
|
||
**Core Functions:** | ||
|
||
- `function balanceOf(address account) external view returns (uint256);` | ||
|
||
- `function transfer(address to, uint256 amount) external payable returns (bool);` | ||
|
||
- **Modified behavior**: Mints `amount` tokens to `to`, requires `msg.value >= transferFee * amount`. | ||
|
||
- `function burn(uint256 amount) external;` | ||
|
||
- Reduces sender’s balance and `totalSupply`. | ||
|
||
**Administration Functions (Owner Only):** | ||
|
||
- `function setMaxSupply(uint256 newMax) external;` | ||
|
||
- `function setTransferFee(uint256 newFee) external;` | ||
|
||
- `function withdrawFees(address payable recipient) external;` | ||
|
||
- Withdraws accumulated native currency fees. | ||
|
||
**Optional Approval Interface (For Compatibility):** | ||
|
||
- `function approve(address spender, uint256 amount) external returns (bool);` | ||
- `function transferFrom(address from, address to, uint256 amount) external payable returns (bool);` | ||
|
||
- **Modified behavior**: Similar to `transfer`, but uses allowance and still mints tokens to `to` rather than redistributing from `from`. | ||
|
||
### Events | ||
|
||
- `event Transfer(address indexed from, address indexed to, uint256 amount);` | ||
|
||
Emitted when tokens are minted to `to` via a transfer call. | ||
|
||
- `event Burn(address indexed burner, uint256 amount);` | ||
|
||
Emitted when `amount` of tokens are burned from an address. | ||
|
||
- `event FeeUpdated(uint256 newFee);` | ||
|
||
Emitted when the owner updates the `transferFee`. | ||
|
||
- `event MaxSupplyUpdated(uint256 newMaxSupply);` | ||
|
||
Emitted when the owner updates `maxSupply`. | ||
|
||
### Compliance with ERC-20 | ||
|
||
The DIFF standard implements the ERC-20 interface but significantly alters the `transfer` and `transferFrom` semantics: | ||
|
||
- **Fungibility**: Each token unit is identical and divisible as in ERC-20. | ||
- **Balances and Transfers**: The `balanceOf` function works as normal. However, `transfer` and `transferFrom` no longer redistribute tokens. Instead, they mint new tokens (up to `maxSupply`). | ||
- **Approvals**: The `approve` and `transferFrom` functions remain, but their logic is unconventional since the sender’s balance is never reduced by transfers. | ||
|
||
While the DIFF standard can be seen as ERC-20 compatible at the interface level, the underlying economics differ substantially. | ||
|
||
## Rationale | ||
|
||
**Use Cases**: | ||
|
||
- **Real-World Asset Backing**: A manufacturer can issue DIFF tokens representing a batch of products (e.g., iPhones). Each token can be redeemed (burned) for one physical item. | ||
|
||
- **Fee-Driven Incentives**: The transfer fee ensures that infinite minting by constant transferring is economically disincentivized. The fee also supports the token issuer or provides a funding mechanism. | ||
|
||
**Design Decisions**: | ||
|
||
- **Unlimited Minting vs. Max Supply**: Allowing minting on every transfer provides a “diffusive” spread of tokens. The `maxSupply` prevents uncontrolled inflation. | ||
|
||
- **Burn Mechanism**: Enables redemption or deflation as tokens are taken out of circulation. | ||
|
||
- **Owner Controls**: The owner (e.g., issuer) can adjust fees and max supply, maintaining flexibility as market conditions change. | ||
|
||
## Backwards Compatibility | ||
|
||
The DIFF standard is interface-compatible with ERC-20 but not behaviorally identical. Any system integrating DIFF tokens should understand the difference in minting on transfer. | ||
|
||
- **Wallets and Exchanges**: Most ERC-20 compatible tools can display balances and initiate transfers. However, the unusual economics (mint on transfer) may confuse users and pricing mechanisms. | ||
- **Allowances and TransferFrom**: Still implemented for interoperability, but the expected logic (debiting `from` balance) does not apply. | ||
|
||
## Test Cases | ||
|
||
1. **Initial Conditions**: | ||
- Deploy contract with `maxSupply = 1,000,000 DIFF`, `transferFee = 0.001 ETH`. | ||
- `totalSupply = 0`. | ||
- Owner sets parameters and verifies via `maxSupply()` and `transferFee()` getters. | ||
|
||
2. **Minting on Transfer**: | ||
- User A calls `transfer(B, 100)` with `msg.value = 0.1 ETH` (assuming `transferFee = 0.001 ETH`). | ||
- Check `balances[B] == 100`, `totalSupply == 100`. | ||
- Check that the contract now holds 0.1 ETH from the fee. | ||
|
||
3. **Exceeding Max Supply**: | ||
- If `totalSupply = 999,950` and someone tries to transfer 100 tokens, causing `totalSupply` to exceed `1,000,000`, the transaction reverts. | ||
|
||
4. **Burning Tokens**: | ||
- User B calls `burn(50)`. | ||
- Check `balances[B] == 50`, `totalSupply == 50` less than before. | ||
- `Burn` event emitted. | ||
|
||
5. **Updating Fee and Withdrawing Funds**: | ||
- Owner calls `setTransferFee(0.002 ETH)`. | ||
- `FeeUpdated` event emitted. | ||
- Owner calls `withdrawFees(ownerAddress)`. | ||
- Check that `ownerAddress` receives accumulated fees. | ||
|
||
## Reference Implementation | ||
|
||
A reference implementation is provided under the asset folder in the EIPs repository. The implementation includes: | ||
|
||
- [`DiffusiveToken.sol`]((../assets/eip-0000/DiffusiveToken.sol)): A basic contract implementing the DIFF standard. | ||
- Interfaces and helper contracts for testing and demonstration purposes. | ||
|
||
## Security Considerations | ||
|
||
- **Reentrancy**: Handle fee transfers using the Checks-Effects-Interactions pattern. Consider `ReentrancyGuard` from OpenZeppelin to prevent reentrant calls. | ||
- **Overflow/Underflow**: Solidity 0.8.x guards against this by default. | ||
- **Contract Balance Management**: Ensure enough native currency is sent to cover fees. Revert on insufficient fees. | ||
- **Access Control**: Only the owner can update `transferFee` and `maxSupply`. Use proper `onlyOwner` modifiers. | ||
|
||
## Copyright | ||
|
||
Copyright and related rights waived via [CC0](../LICENSE.md). |
Oops, something went wrong.