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.
Last updated
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 ()
You can find more about roundId and historic price feeds here:
Full contract code
// 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;
}
}
}