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.
78 lines
3.1 KiB
Solidity
78 lines
3.1 KiB
Solidity
// SPDX-License-Identifier: MIT
|
|
pragma solidity 0.8.23;
|
|
|
|
import "@openzeppelin/contracts/access/Ownable.sol";
|
|
|
|
/**
|
|
* @title ChainalysisOracleWrapper — read-only proxy to Chainalysis's free
|
|
* on-chain sanctions oracle
|
|
* @notice Chainalysis publishes a free, public sanctions oracle on Ethereum
|
|
* mainnet (and other major chains) exposing `isSanctioned(address)`.
|
|
* AERE wraps that oracle on Chain 2800 by holding the deployed
|
|
* address as an immutable, providing the same interface, and
|
|
* letting AERE dApps + institutional integrators query a SINGLE
|
|
* endpoint without having to know the upstream provider's address.
|
|
*
|
|
* This contract makes a forwarding STATICCALL to the upstream
|
|
* oracle. If the upstream rejects (e.g. paused, migrated, doesn't
|
|
* exist on AERE yet), this contract returns false rather than
|
|
* reverting — failing closed but not bricking the dApp.
|
|
*
|
|
* @dev Phase 1 (Q3 2026 ship):
|
|
* - UPSTREAM_ORACLE is settable ONCE by Foundation owner via
|
|
* setUpstream() and immutable after `lockUpstream()`.
|
|
* - Foundation MUST call lockUpstream() before declaring the
|
|
* registry "production-ready". Pre-lock, the contract is
|
|
* considered configurable.
|
|
*
|
|
* Phase 2 (Q1 2027):
|
|
* - Multiple upstream oracles polled, response aggregated via
|
|
* "ANY-true" rule (sanctioned by any source ⇒ sanctioned).
|
|
* - Per-source attestation events for transparency.
|
|
*
|
|
* FORWARD INTERFACE: bool isSanctioned(address)
|
|
* (matches Chainalysis canonical SanctionsList contract)
|
|
*/
|
|
interface IChainalysisUpstream {
|
|
function isSanctioned(address account) external view returns (bool);
|
|
}
|
|
|
|
contract ChainalysisOracleWrapper is Ownable {
|
|
|
|
address public upstreamOracle;
|
|
bool public locked;
|
|
|
|
event UpstreamSet(address oldOracle, address newOracle);
|
|
event UpstreamLocked(address finalOracle);
|
|
|
|
error AlreadyLocked();
|
|
error ZeroAddress();
|
|
|
|
function setUpstream(address newOracle) external onlyOwner {
|
|
if (locked) revert AlreadyLocked();
|
|
if (newOracle == address(0)) revert ZeroAddress();
|
|
emit UpstreamSet(upstreamOracle, newOracle);
|
|
upstreamOracle = newOracle;
|
|
}
|
|
|
|
function lockUpstream() external onlyOwner {
|
|
if (locked) revert AlreadyLocked();
|
|
if (upstreamOracle == address(0)) revert ZeroAddress();
|
|
locked = true;
|
|
emit UpstreamLocked(upstreamOracle);
|
|
}
|
|
|
|
/// @notice Returns true if the upstream Chainalysis oracle reports
|
|
/// `account` as sanctioned. Returns false on any upstream
|
|
/// error (failing closed but never reverting the consumer).
|
|
function isSanctioned(address account) external view returns (bool sanctioned) {
|
|
address up = upstreamOracle;
|
|
if (up == address(0)) return false;
|
|
try IChainalysisUpstream(up).isSanctioned(account) returns (bool s) {
|
|
return s;
|
|
} catch {
|
|
return false;
|
|
}
|
|
}
|
|
}
|