Description:
Smart contract deployed on Ethereum with Factory, Oracle features.
Blockchain: Ethereum
Source Code: View Code On The Blockchain
Solidity Source Code:
{{
"language": "Solidity",
"sources": {
"contracts/ListingOracle.sol": {
"content": "// SPDX-License-Identifier: MIT
pragma solidity ^0.8.24;
import "./interfaces/IStrategyIndex.sol";
/**
* ListingOracle v1.9.2 (Mainnet-Ready)
* ------------------------------------
* - Integrates with external StrategyIndex for PunkLoopEngine.
* - Tracks and updates the on-chain floor.
* - Owner-tunable safety parameters.
* - Optional updater whitelist (approveUpdater) for ConfigAll.s.sol compatibility.
*/
contract ListingOracle {
address public owner;
IStrategyIndex public strategy;
// ---- Last observation ----
uint256 public lastUpdateTs;
uint256 public lastFloorWei;
uint256 public lastSpreadBips;
uint256 public lastListings;
// ---- Tunables ----
uint256 public floorCooldown = 600; // seconds between updates
uint256 public maxSpreadBips = 2000; // 20% tolerance
uint256 public retryDelay = 60; // retry delay on failure
uint256 public minListings = 15; // min listings for validity
// ---- Updater whitelist ----
mapping(address => bool) public approvedUpdater;
bool public whitelistMode; // if false, anyone can call refreshFloor()
// ---- Events ----
event OwnerSet(address indexed owner);
event StrategySet(address indexed strategy);
event TunablesSet(uint256 floorCooldown, uint256 maxSpreadBips, uint256 retryDelay, uint256 minListings);
event FloorUpdated(uint256 floorWei, uint256 listings, uint256 spreadBips);
event UpdaterApproved(address indexed updater, bool approved);
event WhitelistModeSet(bool enabled);
// ---- Errors ----
error NotOwner();
error CooldownActive();
error InvalidResponse();
error TooFewListings();
error NotApproved();
modifier onlyOwner() {
if (msg.sender != owner) revert NotOwner();
_;
}
modifier onlyUpdater() {
if (whitelistMode && !approvedUpdater[msg.sender] && msg.sender != owner) revert NotApproved();
_;
}
constructor(address _strategy) {
require(_strategy != address(0), "ADDR0");
owner = msg.sender;
strategy = IStrategyIndex(_strategy);
emit OwnerSet(owner);
emit StrategySet(_strategy);
}
// ---- Owner admin ----
function setOwner(address _owner) external onlyOwner {
require(_owner != address(0), "ADDR0");
owner = _owner;
emit OwnerSet(_owner);
}
function setStrategy(address _strategy) external onlyOwner {
require(_strategy != address(0), "ADDR0");
strategy = IStrategyIndex(_strategy);
emit StrategySet(_strategy);
}
function setTunables(
uint256 _floorCooldown,
uint256 _maxSpreadBips,
uint256 _retryDelay,
uint256 _minListings
) external onlyOwner {
require(_floorCooldown >= 60 && _retryDelay >= 30, "LOW_INTERVAL");
require(_maxSpreadBips <= 10_000, "BIPS");
floorCooldown = _floorCooldown;
maxSpreadBips = _maxSpreadBips;
retryDelay = _retryDelay;
minListings = _minListings;
emit TunablesSet(_floorCooldown, _maxSpreadBips, _retryDelay, _minListings);
}
// ---- Updater whitelist management ----
function approveUpdater(address updater, bool approved) external onlyOwner {
approvedUpdater[updater] = approved;
emit UpdaterApproved(updater, approved);
}
function setWhitelistMode(bool enabled) external onlyOwner {
whitelistMode = enabled;
emit WhitelistModeSet(enabled);
}
// ---- Public view helpers ----
function latestFloor() external view returns (uint256) {
return lastFloorWei;
}
function preferredListing()
external
view
returns (bool ok, uint256 punkId, uint256 priceWei, address updater)
{
try strategy.globalFloor() returns (uint256 floor) {
return (floor > 0, 0, floor, address(strategy));
} catch {
return (false, 0, 0, address(strategy));
}
}
// ---- Active updater ----
function refreshFloor() external onlyUpdater {
uint256 nowTs = block.timestamp;
if (nowTs < lastUpdateTs + floorCooldown) revert CooldownActive();
(bool ok, , uint256 newFloor, ) = this.preferredListing();
if (!ok || newFloor == 0) revert InvalidResponse();
uint256 prevFloor = lastFloorWei;
if (prevFloor > 0) {
uint256 spread = prevFloor > newFloor
? ((prevFloor - newFloor) * 10_000) / prevFloor
: ((newFloor - prevFloor) * 10_000) / prevFloor;
if (spread > maxSpreadBips) revert InvalidResponse();
lastSpreadBips = spread;
}
// Placeholder: assume listings >= minListings for trusted oracle feed
uint256 listings = minListings;
if (listings < minListings) revert TooFewListings();
lastUpdateTs = nowTs;
lastFloorWei = newFloor;
lastListings = listings;
emit FloorUpdated(newFloor, listings, lastSpreadBips);
}
receive() external payable {}
}
"
},
"contracts/interfaces/IStrategyIndex.sol": {
"content": "// SPDX-License-Identifier: MIT
pragma solidity ^0.8.24;
interface IStrategyIndex {
/// Buy a Punk and relist it on-chain.
function buyPunkAndRelist(uint256 punkId) external payable;
/// Return the global floor price (in wei) for listed Punks.
function globalFloor() external view returns (uint256);
/// (Optional) Return the listing price for a specific Punk.
function getPunkPrice(uint256 punkId) external view returns (uint256);
}
"
}
},
"settings": {
"remappings": [
"forge-std/=lib/forge-std/src/"
],
"optimizer": {
"enabled": true,
"runs": 400
},
"metadata": {
"useLiteralContent": false,
"bytecodeHash": "ipfs",
"appendCBOR": true
},
"outputSelection": {
"*": {
"*": [
"evm.bytecode",
"evm.deployedBytecode",
"devdoc",
"userdoc",
"metadata",
"abi"
]
}
},
"evmVersion": "cancun",
"viaIR": true
}
}}
Submitted on: 2025-10-29 17:21:09
Comments
Log in to comment.
No comments yet.