aere-contracts/contracts/AereTreasury.sol
Aere Network a13a649b77
Some checks are pending
contracts-ci / Install (lockfile) → compile → full test suite (push) Waiting to run
contracts-ci / PQC known-answer tests (NIST vectors) (push) Waiting to run
contracts-ci / Coverage (scoped, with artifacts) (push) Waiting to run
Initial public release
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.
2026-07-20 01:02:37 +03:00

64 lines
2.3 KiB
Solidity

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.19;
import "@openzeppelin/contracts/access/Ownable.sol";
import "@openzeppelin/contracts/security/ReentrancyGuard.sol";
/**
* @title AereTreasury
* @notice DAO treasury for AERE Network. Holds protocol-owned AERE.
* @dev Spends are queued by the owner (governance contract post-handover) with a
* timelock; anyone can execute after the delay. Provides transparency and
* gives the community a window to react to malicious proposals.
*/
contract AereTreasury is Ownable, ReentrancyGuard {
uint256 public constant TIMELOCK = 2 days;
struct Spend {
address to;
uint256 amount;
uint64 eta;
bool executed;
bool cancelled;
string reason;
}
Spend[] public spends;
event Funded(address indexed from, uint256 amount);
event SpendQueued(uint256 indexed id, address indexed to, uint256 amount, uint64 eta, string reason);
event SpendExecuted(uint256 indexed id);
event SpendCancelled(uint256 indexed id);
receive() external payable { emit Funded(msg.sender, msg.value); }
function queueSpend(address to, uint256 amount, string calldata reason) external onlyOwner returns (uint256 id) {
require(to != address(0) && amount > 0, "params");
require(amount <= address(this).balance, "insufficient");
uint64 eta = uint64(block.timestamp + TIMELOCK);
spends.push(Spend({to: to, amount: amount, eta: eta, executed: false, cancelled: false, reason: reason}));
id = spends.length - 1;
emit SpendQueued(id, to, amount, eta, reason);
}
function executeSpend(uint256 id) external nonReentrant {
Spend storage s = spends[id];
require(!s.executed && !s.cancelled, "done");
require(block.timestamp >= s.eta, "timelock");
require(address(this).balance >= s.amount, "balance");
s.executed = true;
(bool ok, ) = s.to.call{value: s.amount}("");
require(ok, "transfer");
emit SpendExecuted(id);
}
function cancelSpend(uint256 id) external onlyOwner {
Spend storage s = spends[id];
require(!s.executed && !s.cancelled, "done");
s.cancelled = true;
emit SpendCancelled(id);
}
function spendCount() external view returns (uint256) { return spends.length; }
}