-
Notifications
You must be signed in to change notification settings - Fork 195
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #370 from lidofinance/feature/LIP-6
LIP-6 implementation
- Loading branch information
Showing
18 changed files
with
1,723 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 | ||
); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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; | ||
} | ||
} |
Oops, something went wrong.