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.
64 lines
2.3 KiB
Solidity
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; }
|
|
}
|