settlement-keeper is used to help facilitate Emergency Shutdown of the GEB Protocol. Emergency shutdown is an involved, deterministic process, requiring interaction from all user types: SAFE owners, system coin holders, keepers, protocol token governors, and other GEB Stakeholders. A high level overview is as follows:
- System Shutdown - The Emergency Security Module (ESM) calls
GlobalSettlement.shutdownSystem()function, which freezes the price for each collateral type as well as many parts of the system.
- Processing Period - Next, SAFE owners interact with GlobalSettlement to settle their SAFEs and withdraw excess collateral. Auctions are left to conclude or are terminated prematurely before system coin redemption.
- System Coin Redemption - After the processing period duration
GlobalSettlement.shutdownCooldownhas elapsed, SAFE settlement and all system coin generating processes (auctions) are assumed to have concluded. At this point, system coin holders can begin to claim a proportional amount of each collateral type at a fixed rate.
To prevent a race-condition for system coin holders during Step 3, it's imperative that any SAFEs having a collateralization ratio of less than 100% at Step 1 must be processed during Step 2. The owner of an underwater SAFE would not receive excess collateral, so they lack an incentive to
processSAFE using the
GlobalSettlement contract. Thus, it is the responsibility of a GEB Stakeholder (protocol token holders, large system coin holders, etc) to ensure that the system facilitates a timely system coin redemption phase. The
settlement-keeper is a tool to help stakeholders carry out this responsibility.
The following section assumes familiarity with Emergency Shutdown. Good places to start is the Shutdown Module in the GEB Docs. Functions mentioned are from the implementation contained by the
GlobalSettlement contract, which is located here.
settlement-keeper directly interacts with the
The central goal of the
settlement-keeper is to process all under-collateralized
SAFEs. This accounting step is performed within
GlobalSettlement.processSAFE(), and since it is surrounded by other required/important steps in the Emergency Shutdown, a first iteration of this keeper will help to call most of the other public functions in the
The keeper checks if the system has been shutdown before attempting to
processSAFE all underwater SAFEs and
fastTrackAuction all collateral auctions. After the processing period has been facilitated and the
GlobalSettlement.shutdownCooldown wait time has been reached, it will transition the system into the redemption phase of Emergency Shutdown by calling
GlobalSettlement.calculateCashPrice(). This first iteration of this keeper is naive, as it assumes it's the only keeper and attempts to account for all SAFEs, collateral types, and auctions. Because of this, it's important that the keeper's address has enough ETH to cover the gas costs involved with sending numerous transactions. Any transaction that attempts to call a function that's already been invoked by another Keeper/user would simply fail.
Once the keys to an ethereum address are supplied at startup, the keeper works out of the box. It can either run continuously on a local/virtual machine or be run when the operator becomes aware of Emergency Shutdown. A sample startup script is shown below. When new collateral types are added to the protocol, the operator should pull the latest version of the keeper, which would include contracts associated with the aforementioned collateral types.
settlement-keeper facilitates the processing period, it can be turned off until
GlobalSettlement.shutdownCooldown is nearly reached. Then, at that point, the operator would pass in the
--previous-settlement argument during keeper start in order to bypass the feature that supports the processing period. Continuous operation removes the need for this flag.
The keeper's ethereum address should have enough ETH to cover gas costs and is a function of the protocol's state at the time of shutdown (i.e. more SAFEs to be called with
processSAFE means more required ETH to cover gas costs). The following equation approximates how much ETH is required:
min_ETH = average_gasPrice * [ ( DebtAuctionHouse.terminate_auction_prematurely()_gas * #_of_Debt_Auctions ) + ( PreSettlementSurplusAuctionHouse.terminate_auction_prematurely()_gas * #_of_Surplus_Auctions ) + ( GlobalSettlement.freezeCollateralType(CollateralType)_gas * #_of_Collateral_Types ) + ( GlobalSettlement.fastTrackAuction()_gas * #_of_Collateral_Auctions ) + ( GlobalSettlement.processSAFE()_gas * #_of_Underwater_SAFEs ) + ( AccountingEngine.settleDebt()_gas ) + ( GlobalSettlement.setOutstandingCoinSupply()_gas ) + ( GlobalSettlement.calculateCashPrice(CollateralType)_gas * #_of_Collateral_Types ) ]
Here's an example from the PRAI mainnet demo of the
settleDebt() calls were not done on PRAI settlement and these gas costs are estimates using from MakerDAO's cage-keeper
min_ETH = 50 GWei * [ ( 196605 * 1 ) + ( 154892 * 1 ) + ( 98289 * 1 ) + ( 389191 * 1 ) + ( 115782 * 30 ) + ( 166397 ) + ( 53625 ) + ( 56635 * 1 ) ] min_ETH = 50 GWei * 4589095 min_ETH ~= 0.229 ETH
- Python v3.6.6
- This project requires virtualenv to be installed if you want to use Reflexer's python tools. This helps with making sure that you are running the right version of python and checks that all of the pip packages that are installed in the install.sh are in the right place and have the right versions.
In order to clone the project and install required third-party packages please execute:
git clone https://github.com/reflexer-labs/settlement-keeper.git cd settlement-keeper git submodule update --init --recursive ./install.sh
For some known Ubuntu and macOS issues see the pyflex README.
Sample Startup Script
Make a run-settlement-keeper.sh to easily spin up the settlement-keeper.
#!/bin/bash /full/path/to/settlement-keeper/bin/settlement-keeper \ --rpc-uri 'http://sample.ParityNode.com:8545' \ --network 'kovan' \ --eth-from '0xABCAddress' \ --eth-key 'key_file=/full/path/to/keystoreFile.json,pass_file=/full/path/to/passphrase/file.txt' \ --safe-engine-deployment-block 14374534
- Download docker and docker-compose
This project uses pytest for unit testing. Testing of GEB is
performed on a Dockerized local testchain included in
In order to be able to run tests, please install development dependencies first by executing:
pip3 install -r requirements-dev.txt
You can then run all tests with:
See COPYING file.
YOU (MEANING ANY INDIVIDUAL OR ENTITY ACCESSING, USING OR BOTH THE SOFTWARE INCLUDED IN THIS GITHUB REPOSITORY) EXPRESSLY UNDERSTAND AND AGREE THAT YOUR USE OF THE SOFTWARE IS AT YOUR SOLE RISK. THE SOFTWARE IN THIS GITHUB REPOSITORY IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. YOU RELEASE AUTHORS OR COPYRIGHT HOLDERS FROM ALL LIABILITY FOR YOU HAVING ACQUIRED OR NOT ACQUIRED CONTENT IN THIS GITHUB REPOSITORY. THE AUTHORS OR COPYRIGHT HOLDERS MAKE NO REPRESENTATIONS CONCERNING ANY CONTENT CONTAINED IN OR ACCESSED THROUGH THE SERVICE, AND THE AUTHORS OR COPYRIGHT HOLDERS WILL NOT BE RESPONSIBLE OR LIABLE FOR THE ACCURACY, COPYRIGHT COMPLIANCE, LEGALITY OR DECENCY OF MATERIAL CONTAINED IN OR ACCESSED THROUGH THIS GITHUB REPOSITORY.