Overview
ETH Balance
0 ETH
Eth Value
$0.00More Info
Private Name Tags
ContractCreator
Sponsored
Latest 6 from a total of 6 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
Value | ||||
---|---|---|---|---|---|---|---|---|---|
Transfer Ownersh... | 12504334 | 929 days 4 hrs ago | IN | 0 ETH | 0.00387358 | ||||
Upgrade Validato... | 12503715 | 929 days 6 hrs ago | IN | 0 ETH | 0.00108263 | ||||
Propose New Vali... | 12503703 | 929 days 6 hrs ago | IN | 0 ETH | 0.00278578 | ||||
Upgrade Validato... | 12497254 | 930 days 6 hrs ago | IN | 0 ETH | 0.00268869 | ||||
Propose New Vali... | 12497252 | 930 days 6 hrs ago | IN | 0 ETH | 0.00916922 | ||||
0x60806040 | 12477502 | 933 days 8 hrs ago | IN | Contract Creation | 0 ETH | 0.05848035 |
View more zero value Internal Transactions in Advanced View mode
Advanced mode:
Loading...
Loading
Similar Match Source Code This contract matches the deployed Bytecode of the Source Code for Contract 0x264BDD...fDd50236 The constructor portion of the code might be different and could alter the actual behaviour of the contract
Contract Name:
ValidatorProxy
Compiler Version
v0.8.4+commit.c7e474f2
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import "./ConfirmedOwner.sol"; import "../interfaces/AggregatorValidatorInterface.sol"; import "../interfaces/TypeAndVersionInterface.sol"; contract ValidatorProxy is AggregatorValidatorInterface, TypeAndVersionInterface, ConfirmedOwner { /// @notice Uses a single storage slot to store the current address struct AggregatorConfiguration { address target; bool hasNewProposal; } struct ValidatorConfiguration { AggregatorValidatorInterface target; bool hasNewProposal; } // Configuration for the current aggregator AggregatorConfiguration private s_currentAggregator; // Proposed aggregator address address private s_proposedAggregator; // Configuration for the current validator ValidatorConfiguration private s_currentValidator; // Proposed validator address AggregatorValidatorInterface private s_proposedValidator; event AggregatorProposed( address indexed aggregator ); event AggregatorUpgraded( address indexed previous, address indexed current ); event ValidatorProposed( AggregatorValidatorInterface indexed validator ); event ValidatorUpgraded( AggregatorValidatorInterface indexed previous, AggregatorValidatorInterface indexed current ); /// @notice The proposed aggregator called validate, but the call was not passed on to any validators event ProposedAggregatorValidateCall( address indexed proposed, uint256 previousRoundId, int256 previousAnswer, uint256 currentRoundId, int256 currentAnswer ); /** * @notice Construct the ValidatorProxy with an aggregator and a validator * @param aggregator address * @param validator address */ constructor( address aggregator, AggregatorValidatorInterface validator ) ConfirmedOwner(msg.sender) { s_currentAggregator = AggregatorConfiguration({ target: aggregator, hasNewProposal: false }); s_currentValidator = ValidatorConfiguration({ target: validator, hasNewProposal: false }); } /** * @notice Validate a transmission * @dev Must be called by either the `s_currentAggregator.target`, or the `s_proposedAggregator`. * If called by the `s_currentAggregator.target` this function passes the call on to the `s_currentValidator.target` * and the `s_proposedValidator`, if it is set. * If called by the `s_proposedAggregator` this function emits a `ProposedAggregatorValidateCall` to signal that * the call was received. * @dev To guard against external `validate` calls reverting, we use raw calls here. * We favour `call` over try-catch to ensure that failures are avoided even if the validator address is incorrectly * set as a non-contract address. * @dev If the `aggregator` and `validator` are the same contract or collude, this could exhibit reentrancy behavior. * However, since that contract would have to be explicitly written for reentrancy and that the `owner` would have * to configure this contract to use that malicious contract, we refrain from using mutex or check here. * @dev This does not perform any checks on any roundId, so it is possible that a validator receive different reports * for the same roundId at different points in time. Validator implementations should be aware of this. * @param previousRoundId uint256 * @param previousAnswer int256 * @param currentRoundId uint256 * @param currentAnswer int256 * @return bool */ function validate( uint256 previousRoundId, int256 previousAnswer, uint256 currentRoundId, int256 currentAnswer ) external override returns ( bool ) { address currentAggregator = s_currentAggregator.target; if (msg.sender != currentAggregator) { address proposedAggregator = s_proposedAggregator; require(msg.sender == proposedAggregator, "Not a configured aggregator"); // If the aggregator is still in proposed state, emit an event and don't push to any validator. // This is to confirm that `validate` is being called prior to upgrade. emit ProposedAggregatorValidateCall( proposedAggregator, previousRoundId, previousAnswer, currentRoundId, currentAnswer ); return true; } // Send the validate call to the current validator ValidatorConfiguration memory currentValidator = s_currentValidator; address currentValidatorAddress = address(currentValidator.target); require(currentValidatorAddress != address(0), "No validator set"); currentValidatorAddress.call( abi.encodeWithSelector( AggregatorValidatorInterface.validate.selector, previousRoundId, previousAnswer, currentRoundId, currentAnswer ) ); // If there is a new proposed validator, send the validate call to that validator also if (currentValidator.hasNewProposal) { address(s_proposedValidator).call( abi.encodeWithSelector( AggregatorValidatorInterface.validate.selector, previousRoundId, previousAnswer, currentRoundId, currentAnswer ) ); } return true; } /** AGGREGATOR CONFIGURATION FUNCTIONS **/ /** * @notice Propose an aggregator * @dev A zero address can be used to unset the proposed aggregator. Only owner can call. * @param proposed address */ function proposeNewAggregator( address proposed ) external onlyOwner() { require(s_proposedAggregator != proposed && s_currentAggregator.target != proposed, "Invalid proposal"); s_proposedAggregator = proposed; // If proposed is zero address, hasNewProposal = false s_currentAggregator.hasNewProposal = (proposed != address(0)); emit AggregatorProposed(proposed); } /** * @notice Upgrade the aggregator by setting the current aggregator as the proposed aggregator. * @dev Must have a proposed aggregator. Only owner can call. */ function upgradeAggregator() external onlyOwner() { // Get configuration in memory AggregatorConfiguration memory current = s_currentAggregator; address previous = current.target; address proposed = s_proposedAggregator; // Perform the upgrade require(current.hasNewProposal, "No proposal"); s_currentAggregator = AggregatorConfiguration({ target: proposed, hasNewProposal: false }); delete s_proposedAggregator; emit AggregatorUpgraded(previous, proposed); } /** * @notice Get aggregator details * @return current address * @return hasProposal bool * @return proposed address */ function getAggregators() external view returns( address current, bool hasProposal, address proposed ) { current = s_currentAggregator.target; hasProposal = s_currentAggregator.hasNewProposal; proposed = s_proposedAggregator; } /** VALIDATOR CONFIGURATION FUNCTIONS **/ /** * @notice Propose an validator * @dev A zero address can be used to unset the proposed validator. Only owner can call. * @param proposed address */ function proposeNewValidator( AggregatorValidatorInterface proposed ) external onlyOwner() { require(s_proposedValidator != proposed && s_currentValidator.target != proposed, "Invalid proposal"); s_proposedValidator = proposed; // If proposed is zero address, hasNewProposal = false s_currentValidator.hasNewProposal = (address(proposed) != address(0)); emit ValidatorProposed(proposed); } /** * @notice Upgrade the validator by setting the current validator as the proposed validator. * @dev Must have a proposed validator. Only owner can call. */ function upgradeValidator() external onlyOwner() { // Get configuration in memory ValidatorConfiguration memory current = s_currentValidator; AggregatorValidatorInterface previous = current.target; AggregatorValidatorInterface proposed = s_proposedValidator; // Perform the upgrade require(current.hasNewProposal, "No proposal"); s_currentValidator = ValidatorConfiguration({ target: proposed, hasNewProposal: false }); delete s_proposedValidator; emit ValidatorUpgraded(previous, proposed); } /** * @notice Get validator details * @return current address * @return hasProposal bool * @return proposed address */ function getValidators() external view returns( AggregatorValidatorInterface current, bool hasProposal, AggregatorValidatorInterface proposed ) { current = s_currentValidator.target; hasProposal = s_currentValidator.hasNewProposal; proposed = s_proposedValidator; } /** * @notice The type and version of this contract * @return Type and version string */ function typeAndVersion() external pure virtual override returns ( string memory ) { return "ValidatorProxy 1.0.0"; } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; /** * @title The ConfirmedOwner contract * @notice A contract with helpers for basic contract ownership. */ contract ConfirmedOwner { 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) { s_owner = newOwner; } /** * @notice Allows an owner to begin transferring ownership to a new address, * pending. */ function transferOwnership( address to ) external onlyOwner() { require(to != msg.sender, "Cannot transfer to self"); s_pendingOwner = to; emit OwnershipTransferRequested(s_owner, to); } /** * @notice Allows an ownership transfer to be completed by the recipient. */ function acceptOwnership() external { 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); } /** * @notice Get the current owner */ function owner() public view returns ( address ) { return s_owner; } /** * @notice Reverts if called by anyone other than the contract owner. */ modifier onlyOwner() { require(msg.sender == s_owner, "Only callable by owner"); _; } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; interface AggregatorValidatorInterface { function validate( uint256 previousRoundId, int256 previousAnswer, uint256 currentRoundId, int256 currentAnswer ) external returns ( bool ); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; abstract contract TypeAndVersionInterface{ function typeAndVersion() external pure virtual returns ( string memory ); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import "../interfaces/AggregatorValidatorInterface.sol"; contract MockAggregatorValidator is AggregatorValidatorInterface { uint8 immutable id; constructor(uint8 id_) { id = id_; } event ValidateCalled( uint8 id, uint256 previousRoundId, int256 previousAnswer, uint256 currentRoundId, int256 currentAnswer ); function validate( uint256 previousRoundId, int256 previousAnswer, uint256 currentRoundId, int256 currentAnswer ) external override returns ( bool ) { emit ValidateCalled(id, previousRoundId, previousAnswer, currentRoundId, currentAnswer); return true; } }
{ "optimizer": { "enabled": true, "runs": 200 }, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "abi" ] } } }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[{"internalType":"address","name":"aggregator","type":"address"},{"internalType":"contract AggregatorValidatorInterface","name":"validator","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"aggregator","type":"address"}],"name":"AggregatorProposed","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previous","type":"address"},{"indexed":true,"internalType":"address","name":"current","type":"address"}],"name":"AggregatorUpgraded","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":true,"internalType":"address","name":"proposed","type":"address"},{"indexed":false,"internalType":"uint256","name":"previousRoundId","type":"uint256"},{"indexed":false,"internalType":"int256","name":"previousAnswer","type":"int256"},{"indexed":false,"internalType":"uint256","name":"currentRoundId","type":"uint256"},{"indexed":false,"internalType":"int256","name":"currentAnswer","type":"int256"}],"name":"ProposedAggregatorValidateCall","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"contract AggregatorValidatorInterface","name":"validator","type":"address"}],"name":"ValidatorProposed","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"contract AggregatorValidatorInterface","name":"previous","type":"address"},{"indexed":true,"internalType":"contract AggregatorValidatorInterface","name":"current","type":"address"}],"name":"ValidatorUpgraded","type":"event"},{"inputs":[],"name":"acceptOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"getAggregators","outputs":[{"internalType":"address","name":"current","type":"address"},{"internalType":"bool","name":"hasProposal","type":"bool"},{"internalType":"address","name":"proposed","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getValidators","outputs":[{"internalType":"contract AggregatorValidatorInterface","name":"current","type":"address"},{"internalType":"bool","name":"hasProposal","type":"bool"},{"internalType":"contract AggregatorValidatorInterface","name":"proposed","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"proposed","type":"address"}],"name":"proposeNewAggregator","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract AggregatorValidatorInterface","name":"proposed","type":"address"}],"name":"proposeNewValidator","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"typeAndVersion","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"upgradeAggregator","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"upgradeValidator","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"previousRoundId","type":"uint256"},{"internalType":"int256","name":"previousAnswer","type":"int256"},{"internalType":"uint256","name":"currentRoundId","type":"uint256"},{"internalType":"int256","name":"currentAnswer","type":"int256"}],"name":"validate","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"}]
Deployed Bytecode
0x608060405234801561001057600080fd5b50600436106100a95760003560e01c80638da5cb5b116100715780638da5cb5b1461015b57806394ce943b14610176578063b7ab4db514610189578063beed9b51146101ac578063c97f7856146101cf578063f2fde38b146101d757600080fd5b8063181f5a77146100ae57806359112a4e146100ed5780637903677f1461010257806379ba50971461010a5780637ee7f7d114610112575b600080fd5b6040805180820182526014815273056616c696461746f7250726f787920312e302e360641b602082015290516100e49190610a8b565b60405180910390f35b6101006100fb366004610a1b565b6101ea565b005b6101006102e9565b6101006103f4565b6002546003546001600160a01b0380831692600160a01b900460ff1691165b604080516001600160a01b03948516815292151560208401529216918101919091526060016100e4565b6000546040516001600160a01b0390911681526020016100e4565b610100610184366004610a1b565b61049e565b6004546005546001600160a01b0380831692600160a01b900460ff169116610131565b6101bf6101ba366004610a3e565b610593565b60405190151581526020016100e4565b61010061083c565b6101006101e5366004610a1b565b610947565b6000546001600160a01b0316331461021d5760405162461bcd60e51b815260040161021490610abe565b60405180910390fd5b6003546001600160a01b0382811691161480159061024957506002546001600160a01b03828116911614155b6102885760405162461bcd60e51b815260206004820152601060248201526f125b9d985b1a59081c1c9bdc1bdcd85b60821b6044820152606401610214565b600380546001600160a01b0319166001600160a01b0383169081179091556002805460ff60a01b1916821515600160a01b021790556040517f5f9c9d260db95e6065c958ac4462171e7a8e70c0c5a7e1864ec8e425c3348de790600090a250565b6000546001600160a01b031633146103135760405162461bcd60e51b815260040161021490610abe565b604080518082019091526004546001600160a01b03808216808452600160a01b90920460ff16151560208401819052600554909116906103835760405162461bcd60e51b815260206004820152600b60248201526a139bc81c1c9bdc1bdcd85b60aa1b6044820152606401610214565b6040805180820182526001600160a01b0380841680835260006020909301839052600480546001600160a81b03191682179055600580546001600160a01b03191690559251908516917fb78a7598213b871cdb0b5cf984a129fa34c321bfd3b74073ba5147e0e3f1c33c91a3505050565b6001546001600160a01b031633146104475760405162461bcd60e51b815260206004820152601660248201527526bab9ba10313290383937b837b9b2b21037bbb732b960511b6044820152606401610214565b60008054336001600160a01b0319808316821784556001805490911690556040516001600160a01b0390921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b6000546001600160a01b031633146104c85760405162461bcd60e51b815260040161021490610abe565b6005546001600160a01b038281169116148015906104f457506004546001600160a01b03828116911614155b6105335760405162461bcd60e51b815260206004820152601060248201526f125b9d985b1a59081c1c9bdc1bdcd85b60821b6044820152606401610214565b600580546001600160a01b0319166001600160a01b0383169081179091556004805460ff60a01b1916821515600160a01b021790556040517e2d79d30d9a290b4aa306dc3542d81c243b1f679b4083044b9723d2378600be90600090a250565b6002546000906001600160a01b0316338114610662576003546001600160a01b03163381146106045760405162461bcd60e51b815260206004820152601b60248201527f4e6f74206120636f6e666967757265642061676772656761746f7200000000006044820152606401610214565b6040805188815260208101889052908101869052606081018590526001600160a01b038216907f5a76b3e9adddfd8f853f50a26cb51f7e4cfef4fbaf1d49df7da37b90119aba789060800160405180910390a2600192505050610834565b604080518082019091526004546001600160a01b038116808352600160a01b90910460ff1615156020830152806106ce5760405162461bcd60e51b815260206004820152601060248201526f139bc81d985b1a59185d1bdc881cd95d60821b6044820152606401610214565b60408051602481018a9052604481018990526064810188905260848082018890528251808303909101815260a490910182526020810180516001600160e01b031663beed9b5160e01b17905290516001600160a01b0383169161073091610a6f565b6000604051808303816000865af19150503d806000811461076d576040519150601f19603f3d011682016040523d82523d6000602084013e610772565b606091505b50505081602001511561082c5760055460408051602481018b9052604481018a90526064810189905260848082018990528251808303909101815260a490910182526020810180516001600160e01b031663beed9b5160e01b17905290516001600160a01b03909216916107e69190610a6f565b6000604051808303816000865af19150503d8060008114610823576040519150601f19603f3d011682016040523d82523d6000602084013e610828565b606091505b5050505b600193505050505b949350505050565b6000546001600160a01b031633146108665760405162461bcd60e51b815260040161021490610abe565b604080518082019091526002546001600160a01b03808216808452600160a01b90920460ff16151560208401819052600354909116906108d65760405162461bcd60e51b815260206004820152600b60248201526a139bc81c1c9bdc1bdcd85b60aa1b6044820152606401610214565b6040805180820182526001600160a01b0380841680835260006020909301839052600280546001600160a81b03191682179055600380546001600160a01b03191690559251908516917f7005ddb42f7ac176ef55c6adb46b53f52e2832c77e915dad61a643841466ea2191a3505050565b6000546001600160a01b031633146109715760405162461bcd60e51b815260040161021490610abe565b6001600160a01b0381163314156109ca5760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401610214565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b600060208284031215610a2c578081fd5b8135610a3781610b1e565b9392505050565b60008060008060808587031215610a53578283fd5b5050823594602084013594506040840135936060013592509050565b60008251610a81818460208701610aee565b9190910192915050565b6020815260008251806020840152610aaa816040850160208701610aee565b601f01601f19169190910160400192915050565b60208082526016908201527527b7363c9031b0b63630b1363290313c9037bbb732b960511b604082015260600190565b60005b83811015610b09578181015183820152602001610af1565b83811115610b18576000848401525b50505050565b6001600160a01b0381168114610b3357600080fd5b5056fea2646970667358221220667756bba087de6ff4730b3a7600fcf70e66602c0f0f6a70f02472b4302ce54f64736f6c63430008040033
Loading...
Loading
Loading...
Loading
Make sure to use the "Vote Down" button for any spammy posts, and the "Vote Up" for interesting conversations.
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.