The following is an example of a settlement contract which determines the outcome of an Ante based on historic price of USDC which is fetched from a Chainlink price feed.
In order for B side to win the commitment, someone needs to provide a Chainlink roundId as a proof of a depeg of USDC. This is achieved by calling: the setDepegRoundId function directly on the settlement contract
This contract uses a historic data feed because it might be hard for someone to catch the exact moment when the asset depegs. But with an oracle like Chainlink, if the depeg happens for a long enough period or with a big enough spread, then you can prove that the depeg happened in the past.
Make sure that the oracle heartbeat and deviation are suitable for your commitment (https://docs.chain.link/data-feeds/price-feeds/addresses?network=ethereum&page=1&search=USDC%2FUSD)
// SPDX-License-Identifier: GPL-3.0-only
pragma solidity 0.8.21;
import {IAnteSettlement} from "../../interfaces/IAnteSettlement.sol";
import {IAnteMetaPool} from "../../interfaces/IAnteMetaPool.sol";
// Chainlink Aggragator interface
// import "@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol";
interface AggregatorV3Interface {
function getRoundData(
uint80 _roundId
)
external
view
returns (uint80 roundId, int256 answer, uint256 startedAt, uint256 updatedAt, uint80 answeredInRound);
}
/**
* Contract used for settling a commitment based on USDC peg to USD.
* The data is fetched using Chainlink historic feed.
* https://docs.chain.link/data-feeds/historical-data
* A Chainlink roundId needs to be submitted before cut-off time in order
* to determine if there was a depeg. Otherwise, the A side will be considered
* the winner.
*/
contract AnteSettlementByUSDCDepeg is IAnteSettlement {
/// @notice Date after you can no longer submit an roundId
uint256 public constant END_DATE = 1704060000; // 01/01/2024 00:00:00
/// @notice Price of USDC in USD with 8 decimals.
/// If the value is below this price, B side becomes the winner
int public constant PRICE_THRESHOLD = 90000000; // 0.9 USD
/**
* @notice The Chainlink historical price feed address
* Network: Ethereum Mainnet
* Aggregator: USDC/USD
* Address: 0x8fFfFfd4AfB6115b954Bd326cbe7B4BA576818f6
*/
address public constant FEED_ADDR = 0x8fFfFfd4AfB6115b954Bd326cbe7B4BA576818f6;
uint80 public depegRoundId;
error Expired();
error InvalidProof();
event RoundIdSet(uint80 roundId);
function setDepegRoundId(uint80 _roundId) external {
AggregatorV3Interface dataFeed = AggregatorV3Interface(FEED_ADDR);
// prettier-ignore
(
/* uint80 roundID */,
int price,
/*uint startedAt*/,
uint updatedAt,
/*uint80 answeredInRound*/
) = dataFeed.getRoundData(_roundId);
if (updatedAt > END_DATE) {
revert Expired();
}
if (price >= PRICE_THRESHOLD) {
revert InvalidProof();
}
depegRoundId = _roundId;
emit RoundIdSet(_roundId);
}
function settle(bytes memory /*data*/) external view returns (WinningSide) {
if (depegRoundId > 0) {
return WinningSide.B;
} else {
return WinningSide.A;
}
}
}