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.
237 lines
8.1 KiB
Solidity
237 lines
8.1 KiB
Solidity
// SPDX-License-Identifier: MIT
|
|
pragma solidity ^0.8.23;
|
|
|
|
/**
|
|
* @title CoverageProbes
|
|
* @notice TEST-ONLY helpers for the round-2 branch-coverage suite. None of these
|
|
* is deployed to any network; they exist purely so that failure branches
|
|
* which cannot be driven by an EOA become reachable from Hardhat.
|
|
*
|
|
* They are excluded from coverage instrumentation (see .solcover.js) so
|
|
* the measured per-file table stays apples-to-apples with the baseline.
|
|
*/
|
|
|
|
/// @notice Refuses every plain AERE transfer (no receive, no fallback), but can
|
|
/// still ORIGINATE calls via `exec`. This is what makes the
|
|
/// `(bool ok, ) = x.call{value: v}(""); require(ok)` FALSE branches
|
|
/// reachable: an EOA recipient always accepts value, a contract with no
|
|
/// receive() does not.
|
|
contract EtherRejector {
|
|
/// Forward an arbitrary call so this contract can be the msg.sender that
|
|
/// triggers a payout back to itself (which then fails).
|
|
function exec(address target, bytes calldata data) external returns (bytes memory) {
|
|
(bool ok, bytes memory ret) = target.call(data);
|
|
if (!ok) {
|
|
assembly {
|
|
revert(add(ret, 0x20), mload(ret))
|
|
}
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
/// Same, with value attached (used to register/delegate from a contract).
|
|
function execValue(address target, bytes calldata data, uint256 value) external payable returns (bytes memory) {
|
|
(bool ok, bytes memory ret) = target.call{ value: value }(data);
|
|
if (!ok) {
|
|
assembly {
|
|
revert(add(ret, 0x20), mload(ret))
|
|
}
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
/// Accept an ERC-721 so this contract can hold a fee-stream NFT.
|
|
function onERC721Received(address, address, uint256, bytes calldata) external pure returns (bytes4) {
|
|
return this.onERC721Received.selector;
|
|
}
|
|
|
|
// Deliberately NO receive() and NO fallback(): plain value transfers revert.
|
|
}
|
|
|
|
/// @notice `owner()` returns the zero address, exercising the
|
|
/// `o != address(0)` FALSE side of AereFeeMonetizationV2.controlsContract
|
|
/// (a target with an owner() that answers, but answers zero).
|
|
contract ZeroOwnerProbe {
|
|
function owner() external pure returns (address) {
|
|
return address(0);
|
|
}
|
|
}
|
|
|
|
/// @notice Has code but no `owner()` at all, so the staticcall hits the fallback
|
|
/// and the try/catch CATCH arm in controlsContract is taken.
|
|
contract NoOwnerProbe {
|
|
uint256 public marker = 1;
|
|
}
|
|
|
|
/// @notice Accepts AERE and, on the FIRST value transfer after being armed,
|
|
/// re-enters a target with stored calldata. The re-entry is made with a
|
|
/// low-level call so the ReentrancyGuard's revert is CAUGHT here and the
|
|
/// outer, legitimate call still completes — the same shape as
|
|
/// MockReentrantBountyToken, which is what lets the blocked branch be
|
|
/// observed instead of unwinding the whole transaction.
|
|
contract ReentrantEtherProbe {
|
|
address public target;
|
|
bytes public payload;
|
|
bool public armed;
|
|
bool public reentryAttempted;
|
|
bool public reentryBlocked;
|
|
|
|
function arm(address _target, bytes calldata _payload) external {
|
|
target = _target;
|
|
payload = _payload;
|
|
armed = true;
|
|
reentryAttempted = false;
|
|
reentryBlocked = false;
|
|
}
|
|
|
|
/// Originate a call (so this contract can be the delegator / NFT holder).
|
|
function exec(address to, bytes calldata data) external returns (bytes memory) {
|
|
(bool ok, bytes memory ret) = to.call(data);
|
|
if (!ok) {
|
|
assembly {
|
|
revert(add(ret, 0x20), mload(ret))
|
|
}
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
function execValue(address to, bytes calldata data, uint256 value) external payable returns (bytes memory) {
|
|
(bool ok, bytes memory ret) = to.call{ value: value }(data);
|
|
if (!ok) {
|
|
assembly {
|
|
revert(add(ret, 0x20), mload(ret))
|
|
}
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
function onERC721Received(address, address, uint256, bytes calldata) external pure returns (bytes4) {
|
|
return this.onERC721Received.selector;
|
|
}
|
|
|
|
function _tryReenter() internal {
|
|
if (!armed || target == address(0)) return;
|
|
armed = false; // one-shot, or the guard would be re-tested forever
|
|
reentryAttempted = true;
|
|
(bool ok, ) = target.call(payload);
|
|
reentryBlocked = !ok;
|
|
}
|
|
|
|
receive() external payable {
|
|
_tryReenter();
|
|
}
|
|
}
|
|
|
|
/// @notice ERC20 whose transferFrom re-enters a target once. AereSink.flush pulls
|
|
/// with transferFrom BEFORE it does anything else, so this is the hook
|
|
/// that reaches flush's own ReentrancyGuard.
|
|
contract ReentrantFlushToken {
|
|
mapping(address => uint256) public balanceOf;
|
|
mapping(address => mapping(address => uint256)) public allowance;
|
|
|
|
address public target;
|
|
bytes public payload;
|
|
bool public armed;
|
|
bool public reentryAttempted;
|
|
bool public reentryBlocked;
|
|
|
|
function mint(address to, uint256 amt) external {
|
|
balanceOf[to] += amt;
|
|
}
|
|
|
|
function arm(address _target, bytes calldata _payload) external {
|
|
target = _target;
|
|
payload = _payload;
|
|
armed = true;
|
|
}
|
|
|
|
function approve(address spender, uint256 amt) external returns (bool) {
|
|
allowance[msg.sender][spender] = amt;
|
|
return true;
|
|
}
|
|
|
|
function _tryReenter() internal {
|
|
if (!armed || target == address(0)) return;
|
|
armed = false;
|
|
reentryAttempted = true;
|
|
(bool ok, ) = target.call(payload);
|
|
reentryBlocked = !ok;
|
|
}
|
|
|
|
function transfer(address to, uint256 amt) external returns (bool) {
|
|
balanceOf[msg.sender] -= amt;
|
|
balanceOf[to] += amt;
|
|
return true;
|
|
}
|
|
|
|
function transferFrom(address from, address to, uint256 amt) external returns (bool) {
|
|
_tryReenter();
|
|
balanceOf[from] -= amt;
|
|
balanceOf[to] += amt;
|
|
return true;
|
|
}
|
|
}
|
|
|
|
/// @notice ERC20 whose transfer REVERTS outright (rather than returning false).
|
|
/// AereSink._safeTransfer checks `!ok || (ret.length > 0 && !decode)`;
|
|
/// the return-false token drives the SECOND leg, and only a token that
|
|
/// actually reverts drives the FIRST (`!ok`).
|
|
contract RevertingTransferToken {
|
|
mapping(address => uint256) public balanceOf;
|
|
|
|
function mint(address to, uint256 amt) external {
|
|
balanceOf[to] += amt;
|
|
}
|
|
|
|
function transfer(address, uint256) external pure returns (bool) {
|
|
revert("token: transfer disabled");
|
|
}
|
|
|
|
function transferFrom(address, address, uint256) external pure returns (bool) {
|
|
revert("token: transferFrom disabled");
|
|
}
|
|
|
|
function approve(address, uint256) external pure returns (bool) {
|
|
return true;
|
|
}
|
|
}
|
|
|
|
/// @notice V2-style router whose swap reverts with EMPTY revert data.
|
|
/// AereSink's catch block does `err.length > 0 ? string(err) : "swap-failed"`.
|
|
/// A router that reverts with a reason string drives the TRUE side; only
|
|
/// a bare `revert()` (zero-length returndata) drives the FALSE side.
|
|
contract EmptyRevertRouter {
|
|
function swapExactTokensForTokens(
|
|
uint256,
|
|
uint256,
|
|
address[] calldata,
|
|
address,
|
|
uint256
|
|
) external pure returns (uint256[] memory) {
|
|
revert();
|
|
}
|
|
}
|
|
|
|
/// @notice Price oracle that reverts for ONE designated asset only.
|
|
/// AereSink._computeOracleFloor has TWO nested try/catch arms; the shared
|
|
/// MockPriceOracle can only revert globally, which reaches the OUTER
|
|
/// catch. Reverting for the AERE leg alone is the only way to reach the
|
|
/// INNER catch.
|
|
contract SelectiveRevertOracle {
|
|
mapping(address => uint256) public prices;
|
|
mapping(address => bool) public revertsFor;
|
|
|
|
function setPrice(address asset, uint256 price) external {
|
|
prices[asset] = price;
|
|
}
|
|
|
|
function setRevertFor(address asset, bool b) external {
|
|
revertsFor[asset] = b;
|
|
}
|
|
|
|
function getPrice(address asset) external view returns (uint256) {
|
|
require(!revertsFor[asset], "oracle: asset paused");
|
|
return prices[asset];
|
|
}
|
|
}
|