Skip to content

Commit

Permalink
Merge pull request #370 from lidofinance/feature/LIP-6
Browse files Browse the repository at this point in the history
LIP-6 implementation
  • Loading branch information
TheDZhon authored Jan 16, 2022
2 parents 30377d5 + e935ce2 commit ee1991b
Show file tree
Hide file tree
Showing 18 changed files with 1,723 additions and 0 deletions.
9 changes: 9 additions & 0 deletions contracts/0.4.24/test_helpers/OracleMock.sol
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import "../interfaces/ILido.sol";
*/
contract OracleMock {
ILido private pool;
address private beaconReceiver;

function setPool(address _pool) external {
pool = ILido(_pool);
Expand All @@ -20,4 +21,12 @@ contract OracleMock {
function reportBeacon(uint256 _epochId, uint128 _beaconValidators, uint128 _beaconBalance) external {
pool.pushBeacon(_beaconValidators, _beaconBalance);
}

function setBeaconReportReceiver(address _receiver) {
beaconReceiver = _receiver;
}

function getBeaconReportReceiver() external view returns (address) {
return beaconReceiver;
}
}
50 changes: 50 additions & 0 deletions contracts/0.8.9/CompositePostRebaseBeaconReceiver.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
// SPDX-FileCopyrightText: 2021 Lido <[email protected]>

// SPDX-License-Identifier: GPL-3.0

/* See contracts/COMPILERS.md */
pragma solidity 0.8.9;

import "./OrderedCallbacksArray.sol";
import "./interfaces/IBeaconReportReceiver.sol";

/**
* @title Contract defining an composite post-rebase beacon receiver for the Lido oracle
*
* Contract adds permission modifiers.
* Only the `ORACLE` address can invoke `processLidoOracleReport` function.
*/
contract CompositePostRebaseBeaconReceiver is OrderedCallbacksArray, IBeaconReportReceiver {
address public immutable ORACLE;

modifier onlyOracle() {
require(msg.sender == ORACLE, "MSG_SENDER_MUST_BE_ORACLE");
_;
}

constructor(
address _voting,
address _oracle
) OrderedCallbacksArray(_voting) {
require(_oracle != address(0), "ORACLE_ZERO_ADDRESS");

ORACLE = _oracle;
}

function processLidoOracleReport(
uint256 _postTotalPooledEther,
uint256 _preTotalPooledEther,
uint256 _timeElapsed
) external override onlyOracle {
uint256 callbacksLen = callbacksLength();

for (uint256 brIndex = 0; brIndex < callbacksLen; brIndex++) {
IBeaconReportReceiver(callbacks[brIndex])
.processLidoOracleReport(
_postTotalPooledEther,
_preTotalPooledEther,
_timeElapsed
);
}
}
}
78 changes: 78 additions & 0 deletions contracts/0.8.9/OrderedCallbacksArray.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
// SPDX-FileCopyrightText: 2021 Lido <[email protected]>

// SPDX-License-Identifier: GPL-3.0

/* See contracts/COMPILERS.md */
pragma solidity 0.8.9;

import "./interfaces/IOrderedCallbacksArray.sol";

/**
* @title Contract defining an ordered callbacks array supporting add/insert/remove ops
*
* Contract adds permission modifiers ontop of `IOderedCallbacksArray` interface functions.
* Only the `VOTING` address can invoke storage mutating (add/insert/remove) functions.
*/
contract OrderedCallbacksArray is IOrderedCallbacksArray {
uint256 public constant MAX_CALLBACKS_COUNT = 16;

address public immutable VOTING;

address[] public callbacks;

modifier onlyVoting() {
require(msg.sender == VOTING, "MSG_SENDER_MUST_BE_VOTING");
_;
}

constructor(address _voting) {
require(_voting != address(0), "VOTING_ZERO_ADDRESS");

VOTING = _voting;
}

function callbacksLength() public view override returns (uint256) {
return callbacks.length;
}

function addCallback(address _callback) external override onlyVoting {
_insertCallback(_callback, callbacks.length);
}

function insertCallback(address _callback, uint256 _atIndex) external override onlyVoting {
_insertCallback(_callback, _atIndex);
}

function removeCallback(uint256 _atIndex) external override onlyVoting {
uint256 oldCArrayLength = callbacks.length;
require(_atIndex < oldCArrayLength, "INDEX_IS_OUT_OF_RANGE");

emit CallbackRemoved(callbacks[_atIndex], _atIndex);

for (uint256 cIndex = _atIndex; cIndex < oldCArrayLength-1; cIndex++) {
callbacks[cIndex] = callbacks[cIndex+1];
}

callbacks.pop();
}

function _insertCallback(address _callback, uint256 _atIndex) private {
require(_callback != address(0), "CALLBACK_ZERO_ADDRESS");

uint256 oldCArrayLength = callbacks.length;
require(_atIndex <= oldCArrayLength, "INDEX_IS_OUT_OF_RANGE");
require(oldCArrayLength < MAX_CALLBACKS_COUNT, "MAX_CALLBACKS_COUNT_EXCEEDED");

emit CallbackAdded(_callback, _atIndex);

callbacks.push();

if (oldCArrayLength > 0) {
for (uint256 cIndex = oldCArrayLength; cIndex > _atIndex; cIndex--) {
callbacks[cIndex] = callbacks[cIndex-1];
}
}

callbacks[_atIndex] = _callback;
}
}
Loading

0 comments on commit ee1991b

Please sign in to comment.