编译器
0.8.19+commit.7dd6d404
文件 1 的 14:Client.sol
pragma solidity ^0.8.0;
library Client {
struct EVMTokenAmount {
address token;
uint256 amount;
}
struct Any2EVMMessage {
bytes32 messageId;
uint64 sourceChainSelector;
bytes sender;
bytes data;
EVMTokenAmount[] destTokenAmounts;
}
struct EVM2AnyMessage {
bytes receiver;
bytes data;
EVMTokenAmount[] tokenAmounts;
address feeToken;
bytes extraArgs;
}
bytes4 public constant EVM_EXTRA_ARGS_V1_TAG = 0x97a657c9;
struct EVMExtraArgsV1 {
uint256 gasLimit;
bool strict;
}
function _argsToBytes(EVMExtraArgsV1 memory extraArgs) internal pure returns (bytes memory bts) {
return abi.encodeWithSelector(EVM_EXTRA_ARGS_V1_TAG, extraArgs);
}
}
文件 2 的 14:CommitStore.sol
pragma solidity 0.8.19;
import {TypeAndVersionInterface} from "../interfaces/TypeAndVersionInterface.sol";
import {ICommitStore} from "./interfaces/ICommitStore.sol";
import {IARM} from "./interfaces/IARM.sol";
import {IPriceRegistry} from "./interfaces/IPriceRegistry.sol";
import {OCR2Base} from "./ocr/OCR2Base.sol";
import {Internal} from "./libraries/Internal.sol";
import {MerkleMultiProof} from "./libraries/MerkleMultiProof.sol";
contract CommitStore is ICommitStore, TypeAndVersionInterface, OCR2Base {
error StaleReport();
error PausedError();
error InvalidInterval(Interval interval);
error InvalidRoot();
error InvalidCommitStoreConfig();
error BadARMSignal();
error RootAlreadyCommitted();
event Paused(address account);
event Unpaused(address account);
event ReportAccepted(CommitReport report);
event ConfigSet(StaticConfig staticConfig, DynamicConfig dynamicConfig);
event RootRemoved(bytes32 root);
struct StaticConfig {
uint64 chainSelector;
uint64 sourceChainSelector;
address onRamp;
address armProxy;
}
struct DynamicConfig {
address priceRegistry;
}
struct Interval {
uint64 min;
uint64 max;
}
struct CommitReport {
Internal.PriceUpdates priceUpdates;
Interval interval;
bytes32 merkleRoot;
}
string public constant override typeAndVersion = "CommitStore 1.0.0";
uint64 internal immutable i_chainSelector;
uint64 internal immutable i_sourceChainSelector;
address internal immutable i_onRamp;
address internal immutable i_armProxy;
DynamicConfig internal s_dynamicConfig;
uint64 private s_minSeqNr = 1;
uint40 private s_latestPriceEpochAndRound;
bool private s_paused = false;
mapping(bytes32 merkleRoot => uint256 timestamp) private s_roots;
constructor(StaticConfig memory staticConfig) OCR2Base(false) {
if (
staticConfig.onRamp == address(0) ||
staticConfig.chainSelector == 0 ||
staticConfig.sourceChainSelector == 0 ||
staticConfig.armProxy == address(0)
) revert InvalidCommitStoreConfig();
i_chainSelector = staticConfig.chainSelector;
i_sourceChainSelector = staticConfig.sourceChainSelector;
i_onRamp = staticConfig.onRamp;
i_armProxy = staticConfig.armProxy;
}
function getExpectedNextSequenceNumber() external view returns (uint64) {
return s_minSeqNr;
}
function setMinSeqNr(uint64 minSeqNr) external onlyOwner {
s_minSeqNr = minSeqNr;
}
function getLatestPriceEpochAndRound() public view returns (uint64) {
return s_latestPriceEpochAndRound;
}
function setLatestPriceEpochAndRound(uint40 latestPriceEpochAndRound) external onlyOwner {
s_latestPriceEpochAndRound = latestPriceEpochAndRound;
}
function getMerkleRoot(bytes32 root) external view returns (uint256) {
return s_roots[root];
}
function isBlessed(bytes32 root) public view returns (bool) {
return IARM(i_armProxy).isBlessed(IARM.TaggedRoot({commitStore: address(this), root: root}));
}
function resetUnblessedRoots(bytes32[] calldata rootToReset) external onlyOwner {
for (uint256 i = 0; i < rootToReset.length; ++i) {
bytes32 root = rootToReset[i];
if (!isBlessed(root)) {
delete s_roots[root];
emit RootRemoved(root);
}
}
}
function verify(
bytes32[] calldata hashedLeaves,
bytes32[] calldata proofs,
uint256 proofFlagBits
) external view override whenNotPaused returns (uint256 timestamp) {
bytes32 root = MerkleMultiProof.merkleRoot(hashedLeaves, proofs, proofFlagBits);
if (!isBlessed(root)) {
return 0;
}
return s_roots[root];
}
function _report(bytes calldata encodedReport, uint40 epochAndRound) internal override whenNotPaused whenHealthy {
CommitReport memory report = abi.decode(encodedReport, (CommitReport));
if (report.priceUpdates.tokenPriceUpdates.length > 0 || report.priceUpdates.destChainSelector != 0) {
if (s_latestPriceEpochAndRound < epochAndRound) {
s_latestPriceEpochAndRound = epochAndRound;
IPriceRegistry(s_dynamicConfig.priceRegistry).updatePrices(report.priceUpdates);
if (report.merkleRoot == bytes32(0)) return;
} else {
if (report.merkleRoot == bytes32(0)) revert StaleReport();
}
}
if (s_minSeqNr != report.interval.min || report.interval.min > report.interval.max)
revert InvalidInterval(report.interval);
if (report.merkleRoot == bytes32(0)) revert InvalidRoot();
if (s_roots[report.merkleRoot] != 0) revert RootAlreadyCommitted();
s_minSeqNr = report.interval.max + 1;
s_roots[report.merkleRoot] = block.timestamp;
emit ReportAccepted(report);
}
function getStaticConfig() external view returns (StaticConfig memory) {
return
StaticConfig({
chainSelector: i_chainSelector,
sourceChainSelector: i_sourceChainSelector,
onRamp: i_onRamp,
armProxy: i_armProxy
});
}
function getDynamicConfig() external view returns (DynamicConfig memory) {
return s_dynamicConfig;
}
function _beforeSetConfig(bytes memory onchainConfig) internal override {
DynamicConfig memory dynamicConfig = abi.decode(onchainConfig, (DynamicConfig));
if (dynamicConfig.priceRegistry == address(0)) revert InvalidCommitStoreConfig();
s_dynamicConfig = dynamicConfig;
s_latestPriceEpochAndRound = 0;
emit ConfigSet(
StaticConfig({
chainSelector: i_chainSelector,
sourceChainSelector: i_sourceChainSelector,
onRamp: i_onRamp,
armProxy: i_armProxy
}),
dynamicConfig
);
}
function isUnpausedAndARMHealthy() external view returns (bool) {
return !IARM(i_armProxy).isCursed() && !s_paused;
}
function isARMHealthy() external view returns (bool) {
return !IARM(i_armProxy).isCursed();
}
modifier whenHealthy() {
if (IARM(i_armProxy).isCursed()) revert BadARMSignal();
_;
}
modifier whenNotPaused() {
if (paused()) revert PausedError();
_;
}
function paused() public view returns (bool) {
return s_paused;
}
function pause() external onlyOwner {
s_paused = true;
emit Paused(msg.sender);
}
function unpause() external onlyOwner {
s_paused = false;
emit Unpaused(msg.sender);
}
}
文件 3 的 14:ConfirmedOwner.sol
pragma solidity ^0.8.0;
import "./ConfirmedOwnerWithProposal.sol";
contract ConfirmedOwner is ConfirmedOwnerWithProposal {
constructor(address newOwner) ConfirmedOwnerWithProposal(newOwner, address(0)) {}
}
文件 4 的 14:ConfirmedOwnerWithProposal.sol
pragma solidity ^0.8.0;
import "./interfaces/OwnableInterface.sol";
contract ConfirmedOwnerWithProposal is OwnableInterface {
address private s_owner;
address private s_pendingOwner;
event OwnershipTransferRequested(address indexed from, address indexed to);
event OwnershipTransferred(address indexed from, address indexed to);
constructor(address newOwner, address pendingOwner) {
require(newOwner != address(0), "Cannot set owner to zero");
s_owner = newOwner;
if (pendingOwner != address(0)) {
_transferOwnership(pendingOwner);
}
}
function transferOwnership(address to) public override onlyOwner {
_transferOwnership(to);
}
function acceptOwnership() external override {
require(msg.sender == s_pendingOwner, "Must be proposed owner");
address oldOwner = s_owner;
s_owner = msg.sender;
s_pendingOwner = address(0);
emit OwnershipTransferred(oldOwner, msg.sender);
}
function owner() public view override returns (address) {
return s_owner;
}
function _transferOwnership(address to) private {
require(to != msg.sender, "Cannot transfer to self");
s_pendingOwner = to;
emit OwnershipTransferRequested(s_owner, to);
}
function _validateOwnership() internal view {
require(msg.sender == s_owner, "Only callable by owner");
}
modifier onlyOwner() {
_validateOwnership();
_;
}
}
文件 5 的 14:IARM.sol
pragma solidity ^0.8.0;
interface IARM {
struct TaggedRoot {
address commitStore;
bytes32 root;
}
function isBlessed(TaggedRoot calldata taggedRoot) external view returns (bool);
function isCursed() external view returns (bool);
}
文件 6 的 14:ICommitStore.sol
pragma solidity ^0.8.0;
interface ICommitStore {
function verify(
bytes32[] calldata hashedLeaves,
bytes32[] calldata proofs,
uint256 proofFlagBits
) external view returns (uint256 timestamp);
function getExpectedNextSequenceNumber() external view returns (uint64 sequenceNumber);
}
文件 7 的 14:IPriceRegistry.sol
pragma solidity ^0.8.0;
import {Internal} from "../libraries/Internal.sol";
interface IPriceRegistry {
function updatePrices(Internal.PriceUpdates memory priceUpdates) external;
function getTokenPrice(address token) external view returns (Internal.TimestampedUint192Value memory);
function getValidatedTokenPrice(address token) external view returns (uint192);
function getTokenPrices(address[] calldata tokens) external view returns (Internal.TimestampedUint192Value[] memory);
function getDestinationChainGasPrice(
uint64 destChainSelector
) external view returns (Internal.TimestampedUint192Value memory);
function getTokenAndGasPrices(
address token,
uint64 destChainSelector
) external view returns (uint192 tokenPrice, uint192 gasPrice);
function convertTokenAmount(
address fromToken,
uint256 fromTokenAmount,
address toToken
) external view returns (uint256 toTokenAmount);
}
文件 8 的 14:Internal.sol
pragma solidity ^0.8.0;
import {Client} from "./Client.sol";
import {MerkleMultiProof} from "../libraries/MerkleMultiProof.sol";
library Internal {
struct PriceUpdates {
TokenPriceUpdate[] tokenPriceUpdates;
uint64 destChainSelector;
uint192 usdPerUnitGas;
}
struct TokenPriceUpdate {
address sourceToken;
uint192 usdPerToken;
}
struct TimestampedUint192Value {
uint192 value;
uint64 timestamp;
}
struct PoolUpdate {
address token;
address pool;
}
struct ExecutionReport {
EVM2EVMMessage[] messages;
bytes[][] offchainTokenData;
bytes32[] proofs;
uint256 proofFlagBits;
}
struct EVM2EVMMessage {
uint64 sourceChainSelector;
uint64 sequenceNumber;
uint256 feeTokenAmount;
address sender;
uint64 nonce;
uint256 gasLimit;
bool strict;
address receiver;
bytes data;
Client.EVMTokenAmount[] tokenAmounts;
address feeToken;
bytes32 messageId;
}
function _toAny2EVMMessage(
EVM2EVMMessage memory original,
Client.EVMTokenAmount[] memory destTokenAmounts
) internal pure returns (Client.Any2EVMMessage memory message) {
message = Client.Any2EVMMessage({
messageId: original.messageId,
sourceChainSelector: original.sourceChainSelector,
sender: abi.encode(original.sender),
data: original.data,
destTokenAmounts: destTokenAmounts
});
}
bytes32 internal constant EVM_2_EVM_MESSAGE_HASH = keccak256("EVM2EVMMessageEvent");
function _hash(EVM2EVMMessage memory original, bytes32 metadataHash) internal pure returns (bytes32) {
return
keccak256(
abi.encode(
MerkleMultiProof.LEAF_DOMAIN_SEPARATOR,
metadataHash,
original.sequenceNumber,
original.nonce,
original.sender,
original.receiver,
keccak256(original.data),
keccak256(abi.encode(original.tokenAmounts)),
original.gasLimit,
original.strict,
original.feeToken,
original.feeTokenAmount
)
);
}
enum MessageExecutionState {
UNTOUCHED,
IN_PROGRESS,
SUCCESS,
FAILURE
}
}
文件 9 的 14:MerkleMultiProof.sol
pragma solidity ^0.8.0;
library MerkleMultiProof {
bytes32 internal constant LEAF_DOMAIN_SEPARATOR = 0x0000000000000000000000000000000000000000000000000000000000000000;
bytes32 internal constant INTERNAL_DOMAIN_SEPARATOR =
0x0000000000000000000000000000000000000000000000000000000000000001;
uint256 internal constant MAX_NUM_HASHES = 256;
error InvalidProof();
error LeavesCannotBeEmpty();
function merkleRoot(
bytes32[] memory leaves,
bytes32[] memory proofs,
uint256 proofFlagBits
) internal pure returns (bytes32) {
unchecked {
uint256 leavesLen = leaves.length;
uint256 proofsLen = proofs.length;
if (leavesLen == 0) revert LeavesCannotBeEmpty();
if (!(leavesLen <= MAX_NUM_HASHES + 1 && proofsLen <= MAX_NUM_HASHES + 1)) revert InvalidProof();
uint256 totalHashes = leavesLen + proofsLen - 1;
if (!(totalHashes <= MAX_NUM_HASHES)) revert InvalidProof();
if (totalHashes == 0) {
return leaves[0];
}
bytes32[] memory hashes = new bytes32[](totalHashes);
(uint256 leafPos, uint256 hashPos, uint256 proofPos) = (0, 0, 0);
for (uint256 i = 0; i < totalHashes; ++i) {
bytes32 a;
if (proofFlagBits & (1 << i) == (1 << i)) {
if (leafPos < leavesLen) {
a = leaves[leafPos++];
} else {
a = hashes[hashPos++];
}
} else {
a = proofs[proofPos++];
}
bytes32 b;
if (leafPos < leavesLen) {
b = leaves[leafPos++];
} else {
b = hashes[hashPos++];
}
if (!(hashPos <= i)) revert InvalidProof();
hashes[i] = _hashPair(a, b);
}
if (!(hashPos == totalHashes - 1 && leafPos == leavesLen && proofPos == proofsLen)) revert InvalidProof();
return hashes[totalHashes - 1];
}
}
function _hashInternalNode(bytes32 left, bytes32 right) private pure returns (bytes32 hash) {
return keccak256(abi.encode(INTERNAL_DOMAIN_SEPARATOR, left, right));
}
function _hashPair(bytes32 a, bytes32 b) private pure returns (bytes32) {
return a < b ? _hashInternalNode(a, b) : _hashInternalNode(b, a);
}
}
文件 10 的 14:OCR2Abstract.sol
pragma solidity ^0.8.0;
import {TypeAndVersionInterface} from "../../interfaces/TypeAndVersionInterface.sol";
abstract contract OCR2Abstract is TypeAndVersionInterface {
uint256 internal constant MAX_NUM_ORACLES = 31;
event ConfigSet(
uint32 previousConfigBlockNumber,
bytes32 configDigest,
uint64 configCount,
address[] signers,
address[] transmitters,
uint8 f,
bytes onchainConfig,
uint64 offchainConfigVersion,
bytes offchainConfig
);
function setOCR2Config(
address[] memory signers,
address[] memory transmitters,
uint8 f,
bytes memory onchainConfig,
uint64 offchainConfigVersion,
bytes memory offchainConfig
) external virtual;
function latestConfigDetails()
external
view
virtual
returns (uint32 configCount, uint32 blockNumber, bytes32 configDigest);
function _configDigestFromConfigData(
uint256 chainId,
address contractAddress,
uint64 configCount,
address[] memory signers,
address[] memory transmitters,
uint8 f,
bytes memory onchainConfig,
uint64 offchainConfigVersion,
bytes memory offchainConfig
) internal pure returns (bytes32) {
uint256 h = uint256(
keccak256(
abi.encode(
chainId,
contractAddress,
configCount,
signers,
transmitters,
f,
onchainConfig,
offchainConfigVersion,
offchainConfig
)
)
);
uint256 prefixMask = type(uint256).max << (256 - 16);
uint256 prefix = 0x0001 << (256 - 16);
return bytes32((prefix & prefixMask) | (h & ~prefixMask));
}
event Transmitted(bytes32 configDigest, uint32 epoch);
function latestConfigDigestAndEpoch()
external
view
virtual
returns (bool scanLogs, bytes32 configDigest, uint32 epoch);
function transmit(
bytes32[3] calldata reportContext,
bytes calldata report,
bytes32[] calldata rs,
bytes32[] calldata ss,
bytes32 rawVs
) external virtual;
}
文件 11 的 14:OCR2Base.sol
pragma solidity ^0.8.0;
import {OwnerIsCreator} from "../../shared/access/OwnerIsCreator.sol";
import {OCR2Abstract} from "./OCR2Abstract.sol";
abstract contract OCR2Base is OwnerIsCreator, OCR2Abstract {
error InvalidConfig(string message);
error WrongMessageLength(uint256 expected, uint256 actual);
error ConfigDigestMismatch(bytes32 expected, bytes32 actual);
error ForkedChain(uint256 expected, uint256 actual);
error WrongNumberOfSignatures();
error SignaturesOutOfRegistration();
error UnauthorizedTransmitter();
error UnauthorizedSigner();
error NonUniqueSignatures();
error OracleCannotBeZeroAddress();
struct ConfigInfo {
bytes32 latestConfigDigest;
uint8 f;
uint8 n;
}
enum Role {
Unset,
Signer,
Transmitter
}
struct Oracle {
uint8 index;
Role role;
}
ConfigInfo internal s_configInfo;
uint32 internal s_configCount;
uint32 internal s_latestConfigBlockNumber;
mapping(address signerOrTransmitter => Oracle oracle) internal s_oracles;
address[] internal s_signers;
address[] internal s_transmitters;
uint16 private constant TRANSMIT_MSGDATA_CONSTANT_LENGTH_COMPONENT =
4 +
32 *
3 +
32 +
32 +
32 +
32 +
32 +
32 +
32;
bool internal immutable i_uniqueReports;
uint256 internal immutable i_chainID;
constructor(bool uniqueReports) {
i_uniqueReports = uniqueReports;
i_chainID = block.chainid;
}
modifier checkConfigValid(
uint256 numSigners,
uint256 numTransmitters,
uint256 f
) {
if (numSigners > MAX_NUM_ORACLES) revert InvalidConfig("too many signers");
if (f == 0) revert InvalidConfig("f must be positive");
if (numSigners != numTransmitters) revert InvalidConfig("oracle addresses out of registration");
if (numSigners <= 3 * f) revert InvalidConfig("faulty-oracle f too high");
_;
}
function setOCR2Config(
address[] memory signers,
address[] memory transmitters,
uint8 f,
bytes memory onchainConfig,
uint64 offchainConfigVersion,
bytes memory offchainConfig
) external override checkConfigValid(signers.length, transmitters.length, f) onlyOwner {
_beforeSetConfig(onchainConfig);
uint256 oldSignerLength = s_signers.length;
for (uint256 i = 0; i < oldSignerLength; ++i) {
delete s_oracles[s_signers[i]];
delete s_oracles[s_transmitters[i]];
}
uint256 newSignersLength = signers.length;
for (uint256 i = 0; i < newSignersLength; ++i) {
address signer = signers[i];
if (s_oracles[signer].role != Role.Unset) revert InvalidConfig("repeated signer address");
if (signer == address(0)) revert OracleCannotBeZeroAddress();
s_oracles[signer] = Oracle(uint8(i), Role.Signer);
address transmitter = transmitters[i];
if (s_oracles[transmitter].role != Role.Unset) revert InvalidConfig("repeated transmitter address");
if (transmitter == address(0)) revert OracleCannotBeZeroAddress();
s_oracles[transmitter] = Oracle(uint8(i), Role.Transmitter);
}
s_signers = signers;
s_transmitters = transmitters;
s_configInfo.f = f;
s_configInfo.n = uint8(newSignersLength);
s_configInfo.latestConfigDigest = _configDigestFromConfigData(
block.chainid,
address(this),
++s_configCount,
signers,
transmitters,
f,
onchainConfig,
offchainConfigVersion,
offchainConfig
);
uint32 previousConfigBlockNumber = s_latestConfigBlockNumber;
s_latestConfigBlockNumber = uint32(block.number);
emit ConfigSet(
previousConfigBlockNumber,
s_configInfo.latestConfigDigest,
s_configCount,
signers,
transmitters,
f,
onchainConfig,
offchainConfigVersion,
offchainConfig
);
}
function _beforeSetConfig(bytes memory _onchainConfig) internal virtual {}
function getTransmitters() external view returns (address[] memory) {
return s_transmitters;
}
function transmit(
bytes32[3] calldata reportContext,
bytes calldata report,
bytes32[] calldata rs,
bytes32[] calldata ss,
bytes32 rawVs
) external override {
{
_report(report, uint40(uint256(reportContext[1])));
}
bytes32 configDigest = reportContext[0];
ConfigInfo memory configInfo = s_configInfo;
if (configInfo.latestConfigDigest != configDigest)
revert ConfigDigestMismatch(configInfo.latestConfigDigest, configDigest);
if (i_chainID != block.chainid) revert ForkedChain(i_chainID, block.chainid);
emit Transmitted(configDigest, uint32(uint256(reportContext[1]) >> 8));
uint256 expectedNumSignatures;
if (i_uniqueReports) {
expectedNumSignatures = (configInfo.n + configInfo.f) / 2 + 1;
} else {
expectedNumSignatures = configInfo.f + 1;
}
if (rs.length != expectedNumSignatures) revert WrongNumberOfSignatures();
if (rs.length != ss.length) revert SignaturesOutOfRegistration();
{
Oracle memory transmitter = s_oracles[msg.sender];
if (!(transmitter.role == Role.Transmitter && msg.sender == s_transmitters[transmitter.index]))
revert UnauthorizedTransmitter();
}
{
uint256 expectedDataLength = uint256(TRANSMIT_MSGDATA_CONSTANT_LENGTH_COMPONENT) +
report.length +
rs.length *
32 +
ss.length *
32;
if (msg.data.length != expectedDataLength) revert WrongMessageLength(expectedDataLength, msg.data.length);
}
bytes32 h = keccak256(abi.encodePacked(keccak256(report), reportContext));
bool[MAX_NUM_ORACLES] memory signed;
uint256 numberOfSignatures = rs.length;
for (uint256 i = 0; i < numberOfSignatures; ++i) {
address signer = ecrecover(h, uint8(rawVs[i]) + 27, rs[i], ss[i]);
Oracle memory oracle = s_oracles[signer];
if (oracle.role != Role.Signer) revert UnauthorizedSigner();
if (signed[oracle.index]) revert NonUniqueSignatures();
signed[oracle.index] = true;
}
}
function latestConfigDetails()
external
view
override
returns (uint32 configCount, uint32 blockNumber, bytes32 configDigest)
{
return (s_configCount, s_latestConfigBlockNumber, s_configInfo.latestConfigDigest);
}
function latestConfigDigestAndEpoch()
external
view
virtual
override
returns (bool scanLogs, bytes32 configDigest, uint32 epoch)
{
return (true, bytes32(0), uint32(0));
}
function _report(bytes calldata report, uint40 epochAndRound) internal virtual;
}
文件 12 的 14:OwnableInterface.sol
pragma solidity ^0.8.0;
interface OwnableInterface {
function owner() external returns (address);
function transferOwnership(address recipient) external;
function acceptOwnership() external;
}
文件 13 的 14:OwnerIsCreator.sol
pragma solidity ^0.8.0;
import {ConfirmedOwner} from "../../ConfirmedOwner.sol";
contract OwnerIsCreator is ConfirmedOwner {
constructor() ConfirmedOwner(msg.sender) {}
}
文件 14 的 14:TypeAndVersionInterface.sol
pragma solidity ^0.8.0;
abstract contract TypeAndVersionInterface {
function typeAndVersion() external pure virtual returns (string memory);
}
{
"compilationTarget": {
"src/v0.8/ccip/CommitStore.sol": "CommitStore"
},
"evmVersion": "london",
"libraries": {},
"metadata": {
"bytecodeHash": "none"
},
"optimizer": {
"enabled": true,
"runs": 26000
},
"remappings": [
":@eth-optimism/=node_modules/@eth-optimism/",
":@openzeppelin/=node_modules/@openzeppelin/",
":ds-test/=foundry-lib/forge-std/lib/ds-test/src/",
":erc4626-tests/=foundry-lib/openzeppelin-contracts/lib/erc4626-tests/",
":forge-std/=foundry-lib/forge-std/src/",
":hardhat/=node_modules/hardhat/",
":openzeppelin-contracts/=foundry-lib/openzeppelin-contracts/contracts/"
]
}
[{"inputs":[{"components":[{"internalType":"uint64","name":"chainSelector","type":"uint64"},{"internalType":"uint64","name":"sourceChainSelector","type":"uint64"},{"internalType":"address","name":"onRamp","type":"address"},{"internalType":"address","name":"armProxy","type":"address"}],"internalType":"struct CommitStore.StaticConfig","name":"staticConfig","type":"tuple"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"BadARMSignal","type":"error"},{"inputs":[{"internalType":"bytes32","name":"expected","type":"bytes32"},{"internalType":"bytes32","name":"actual","type":"bytes32"}],"name":"ConfigDigestMismatch","type":"error"},{"inputs":[{"internalType":"uint256","name":"expected","type":"uint256"},{"internalType":"uint256","name":"actual","type":"uint256"}],"name":"ForkedChain","type":"error"},{"inputs":[],"name":"InvalidCommitStoreConfig","type":"error"},{"inputs":[{"internalType":"string","name":"message","type":"string"}],"name":"InvalidConfig","type":"error"},{"inputs":[{"components":[{"internalType":"uint64","name":"min","type":"uint64"},{"internalType":"uint64","name":"max","type":"uint64"}],"internalType":"struct CommitStore.Interval","name":"interval","type":"tuple"}],"name":"InvalidInterval","type":"error"},{"inputs":[],"name":"InvalidProof","type":"error"},{"inputs":[],"name":"InvalidRoot","type":"error"},{"inputs":[],"name":"LeavesCannotBeEmpty","type":"error"},{"inputs":[],"name":"NonUniqueSignatures","type":"error"},{"inputs":[],"name":"OracleCannotBeZeroAddress","type":"error"},{"inputs":[],"name":"PausedError","type":"error"},{"inputs":[],"name":"RootAlreadyCommitted","type":"error"},{"inputs":[],"name":"SignaturesOutOfRegistration","type":"error"},{"inputs":[],"name":"StaleReport","type":"error"},{"inputs":[],"name":"UnauthorizedSigner","type":"error"},{"inputs":[],"name":"UnauthorizedTransmitter","type":"error"},{"inputs":[{"internalType":"uint256","name":"expected","type":"uint256"},{"internalType":"uint256","name":"actual","type":"uint256"}],"name":"WrongMessageLength","type":"error"},{"inputs":[],"name":"WrongNumberOfSignatures","type":"error"},{"anonymous":false,"inputs":[{"components":[{"internalType":"uint64","name":"chainSelector","type":"uint64"},{"internalType":"uint64","name":"sourceChainSelector","type":"uint64"},{"internalType":"address","name":"onRamp","type":"address"},{"internalType":"address","name":"armProxy","type":"address"}],"indexed":false,"internalType":"struct CommitStore.StaticConfig","name":"staticConfig","type":"tuple"},{"components":[{"internalType":"address","name":"priceRegistry","type":"address"}],"indexed":false,"internalType":"struct CommitStore.DynamicConfig","name":"dynamicConfig","type":"tuple"}],"name":"ConfigSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint32","name":"previousConfigBlockNumber","type":"uint32"},{"indexed":false,"internalType":"bytes32","name":"configDigest","type":"bytes32"},{"indexed":false,"internalType":"uint64","name":"configCount","type":"uint64"},{"indexed":false,"internalType":"address[]","name":"signers","type":"address[]"},{"indexed":false,"internalType":"address[]","name":"transmitters","type":"address[]"},{"indexed":false,"internalType":"uint8","name":"f","type":"uint8"},{"indexed":false,"internalType":"bytes","name":"onchainConfig","type":"bytes"},{"indexed":false,"internalType":"uint64","name":"offchainConfigVersion","type":"uint64"},{"indexed":false,"internalType":"bytes","name":"offchainConfig","type":"bytes"}],"name":"ConfigSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"}],"name":"OwnershipTransferRequested","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Paused","type":"event"},{"anonymous":false,"inputs":[{"components":[{"components":[{"components":[{"internalType":"address","name":"sourceToken","type":"address"},{"internalType":"uint192","name":"usdPerToken","type":"uint192"}],"internalType":"struct Internal.TokenPriceUpdate[]","name":"tokenPriceUpdates","type":"tuple[]"},{"internalType":"uint64","name":"destChainSelector","type":"uint64"},{"internalType":"uint192","name":"usdPerUnitGas","type":"uint192"}],"internalType":"struct Internal.PriceUpdates","name":"priceUpdates","type":"tuple"},{"components":[{"internalType":"uint64","name":"min","type":"uint64"},{"internalType":"uint64","name":"max","type":"uint64"}],"internalType":"struct CommitStore.Interval","name":"interval","type":"tuple"},{"internalType":"bytes32","name":"merkleRoot","type":"bytes32"}],"indexed":false,"internalType":"struct CommitStore.CommitReport","name":"report","type":"tuple"}],"name":"ReportAccepted","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bytes32","name":"root","type":"bytes32"}],"name":"RootRemoved","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bytes32","name":"configDigest","type":"bytes32"},{"indexed":false,"internalType":"uint32","name":"epoch","type":"uint32"}],"name":"Transmitted","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Unpaused","type":"event"},{"inputs":[],"name":"acceptOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"getDynamicConfig","outputs":[{"components":[{"internalType":"address","name":"priceRegistry","type":"address"}],"internalType":"struct CommitStore.DynamicConfig","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getExpectedNextSequenceNumber","outputs":[{"internalType":"uint64","name":"","type":"uint64"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getLatestPriceEpochAndRound","outputs":[{"internalType":"uint64","name":"","type":"uint64"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"root","type":"bytes32"}],"name":"getMerkleRoot","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getStaticConfig","outputs":[{"components":[{"internalType":"uint64","name":"chainSelector","type":"uint64"},{"internalType":"uint64","name":"sourceChainSelector","type":"uint64"},{"internalType":"address","name":"onRamp","type":"address"},{"internalType":"address","name":"armProxy","type":"address"}],"internalType":"struct CommitStore.StaticConfig","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getTransmitters","outputs":[{"internalType":"address[]","name":"","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"isARMHealthy","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"root","type":"bytes32"}],"name":"isBlessed","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"isUnpausedAndARMHealthy","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"latestConfigDetails","outputs":[{"internalType":"uint32","name":"configCount","type":"uint32"},{"internalType":"uint32","name":"blockNumber","type":"uint32"},{"internalType":"bytes32","name":"configDigest","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"latestConfigDigestAndEpoch","outputs":[{"internalType":"bool","name":"scanLogs","type":"bool"},{"internalType":"bytes32","name":"configDigest","type":"bytes32"},{"internalType":"uint32","name":"epoch","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"paused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32[]","name":"rootToReset","type":"bytes32[]"}],"name":"resetUnblessedRoots","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint40","name":"latestPriceEpochAndRound","type":"uint40"}],"name":"setLatestPriceEpochAndRound","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint64","name":"minSeqNr","type":"uint64"}],"name":"setMinSeqNr","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"signers","type":"address[]"},{"internalType":"address[]","name":"transmitters","type":"address[]"},{"internalType":"uint8","name":"f","type":"uint8"},{"internalType":"bytes","name":"onchainConfig","type":"bytes"},{"internalType":"uint64","name":"offchainConfigVersion","type":"uint64"},{"internalType":"bytes","name":"offchainConfig","type":"bytes"}],"name":"setOCR2Config","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32[3]","name":"reportContext","type":"bytes32[3]"},{"internalType":"bytes","name":"report","type":"bytes"},{"internalType":"bytes32[]","name":"rs","type":"bytes32[]"},{"internalType":"bytes32[]","name":"ss","type":"bytes32[]"},{"internalType":"bytes32","name":"rawVs","type":"bytes32"}],"name":"transmit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"typeAndVersion","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"unpause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32[]","name":"hashedLeaves","type":"bytes32[]"},{"internalType":"bytes32[]","name":"proofs","type":"bytes32[]"},{"internalType":"uint256","name":"proofFlagBits","type":"uint256"}],"name":"verify","outputs":[{"internalType":"uint256","name":"timestamp","type":"uint256"}],"stateMutability":"view","type":"function"}]