Aere Network public source. Everything here can be checked against the live chain (chain id 2800, https://rpc.aere.network). Scope note, stated up front rather than buried: consensus on chain 2800 is classical secp256k1 ECDSA QBFT. The post-quantum work in this repository is at the signature, precompile, account and transport layers. Nothing here makes the consensus post-quantum, and no document in it should be read as claiming so.
91 lines
3.9 KiB
Solidity
91 lines
3.9 KiB
Solidity
// SPDX-License-Identifier: MIT
|
|
pragma solidity ^0.8.19;
|
|
|
|
/**
|
|
* @title AereFeeBurnVault
|
|
* @notice Permanent, on-chain burn destination for protocol fees.
|
|
*
|
|
* Whitepaper §3.3 promises that "up to 37.5% of all transaction fees are
|
|
* permanently obliterated." This contract is the burn endpoint that makes
|
|
* that claim measurable and publicly auditable.
|
|
*
|
|
* Design:
|
|
* - Stateless sink: anyone can send native AERE here via `burn()`, or any
|
|
* ERC-20 via `burnToken()`. The contract has NO withdraw function and
|
|
* NO admin escape hatch — funds that enter are permanently removed
|
|
* from circulation.
|
|
* - Counters: tracks `totalBurnedAERE` and per-token `totalBurnedToken[token]`
|
|
* so the chain's deflation can be queried in a single read.
|
|
* - Sources: protocol contracts that earn fees (AereSwapRouter, the NFT
|
|
* marketplace, future card-fee router, etc.) can route a configurable
|
|
* share to this address — but the vault doesn't care WHO sends; any
|
|
* value arriving here is burned.
|
|
*
|
|
* This contract holds no privilege over any other system. Ownable is not
|
|
* needed because there are no admin operations.
|
|
*/
|
|
|
|
interface IERC20 {
|
|
function transfer(address to, uint256 amount) external returns (bool);
|
|
function transferFrom(address from, address to, uint256 amount) external returns (bool);
|
|
function balanceOf(address account) external view returns (uint256);
|
|
}
|
|
|
|
contract AereFeeBurnVault {
|
|
/// Total native AERE that has flowed into this contract.
|
|
/// Equal to address(this).balance EXCEPT after the eventual
|
|
/// "send to zero-address" sweep — see note below.
|
|
uint256 public totalBurnedAERE;
|
|
|
|
/// Cumulative native AERE actually forwarded to address(0).
|
|
uint256 public totalSentToZero;
|
|
|
|
/// Per-ERC20 lifetime burn counter.
|
|
mapping(address => uint256) public totalBurnedToken;
|
|
|
|
event AereBurned(address indexed from, uint256 amount, uint256 newTotal);
|
|
event TokenBurned(address indexed token, address indexed from, uint256 amount, uint256 newTotal);
|
|
event AereSentToZero(uint256 amount, uint256 newTotalSentToZero);
|
|
|
|
/// Plain ETH transfer = burn.
|
|
receive() external payable {
|
|
totalBurnedAERE += msg.value;
|
|
emit AereBurned(msg.sender, msg.value, totalBurnedAERE);
|
|
}
|
|
|
|
/// Explicit native-AERE burn (same as `receive`, but lets callers attach a tag in the event log).
|
|
function burn() external payable {
|
|
totalBurnedAERE += msg.value;
|
|
emit AereBurned(msg.sender, msg.value, totalBurnedAERE);
|
|
}
|
|
|
|
/// Burn an ERC-20 by pulling it from `msg.sender` via prior approval.
|
|
/// Tokens are accepted but never sent anywhere; they stay on this contract
|
|
/// forever. Counters reflect cumulative arrivals.
|
|
function burnToken(address token, uint256 amount) external {
|
|
require(token != address(0), "BurnVault: zero token");
|
|
require(amount > 0, "BurnVault: zero amount");
|
|
require(IERC20(token).transferFrom(msg.sender, address(this), amount), "BurnVault: transferFrom failed");
|
|
totalBurnedToken[token] += amount;
|
|
emit TokenBurned(token, msg.sender, amount, totalBurnedToken[token]);
|
|
}
|
|
|
|
/// Optional: forward accumulated native AERE to address(0).
|
|
/// QBFT Besu permits sending to address(0); the AERE is then unreachable.
|
|
/// Anyone can call this; it has no parameters and no admin gate. This is
|
|
/// the "obliteration" step — until called, AERE sits on this contract.
|
|
function sweepToZero() external {
|
|
uint256 bal = address(this).balance;
|
|
require(bal > 0, "BurnVault: nothing to sweep");
|
|
totalSentToZero += bal;
|
|
(bool ok, ) = address(0).call{ value: bal }("");
|
|
require(ok, "BurnVault: zero-send failed");
|
|
emit AereSentToZero(bal, totalSentToZero);
|
|
}
|
|
|
|
/// Convenience read.
|
|
function currentAEREBalance() external view returns (uint256) {
|
|
return address(this).balance;
|
|
}
|
|
}
|