diff --git a/README.md b/README.md index e8ab78fae..702c0e19b 100644 --- a/README.md +++ b/README.md @@ -24,10 +24,10 @@ For a much more detailed explanation of the economic design, including an hour-l - [System Design](https://github.com/reserve-protocol/protocol/blob/master/docs/system-design.md): The overall architecture of our system, and some detailed descriptions about what our protocol is _intended_ to do. - [Pause and Freeze States](https://github.com/reserve-protocol/protocol/blob/master/docs/pause-freeze-states.md): An overview of which protocol functions are halted in the paused and frozen states. - [Deployment Variables](https://github.com/reserve-protocol/protocol/blob/master/docs/deployment-variables.md) A detailed description of the governance variables of the protocol. -- [Our Solidity Style](https://github.com/reserve-protocol/protocol/blob/master/docs/solidity-style.md): Common practices, details, and conventions relevant to reading and writing our Solidity source code, estpecially where those go beyond standard practice. +- [Our Solidity Style](https://github.com/reserve-protocol/protocol/blob/master/docs/solidity-style.md): Common practices, details, and conventions relevant to reading and writing our Solidity source code, especially where those go beyond standard practice. - [Writing Collateral Plugins](https://github.com/reserve-protocol/protocol/blob/master/docs/collateral.md): An overview of how to develop collateral plugins and the concepts / questions involved. - [Building on Top](https://github.com/reserve-protocol/protocol/blob/master/docs/build-on-top.md): How to build on top of Reserve, including information about long-lived fork environments. -- [MEV](https://github.com/reserve-protocol/protocol/blob/master/docs/mev.md): A resource for MEV searchers and others looking to interact with the deployed protocol programatically. +- [MEV](https://github.com/reserve-protocol/protocol/blob/master/docs/mev.md): A resource for MEV searchers and others looking to interact with the deployed protocol programmatically. - [Rebalancing Algorithm](https://github.com/reserve-protocol/protocol/blob/master/docs/recollateralization.md): Description of our trading algorithm during the recollateralization process - [Changelog](https://github.com/reserve-protocol/protocol/blob/master/CHANGELOG.md): Release changelog @@ -64,7 +64,7 @@ Deployed collateral plugin addresses and their configuration parameters can be f We have a `p0` and `p1` implementation for each contract in our core system. The `p0` version is our _specification_ prototype, and is intended to be as easy as possible to understand. The `p1` version should behave identically, except that it employs substantial optimizations and more complicated algorithms in order to achieve lower gas costs. -We implement and maintain both of these systems in the name of correctness. Implementing p0 helps us to specify the exact intended behavior of the protocol without needing to deal simultaneously with gas optimization; maintaining equivalent behavior of both serves as a substantial extra form of testing. The behavior of each contract in `p1` should be _identical_ to the behavior of the corresponding contract in `p0`, so we can perform [differential testing](https://en.wikipedia.org/wiki/Differential_testing) between them - checking that they behave identicially, both in our explicit tests and in arbitrary randomized tests. +We implement and maintain both of these systems in the name of correctness. Implementing p0 helps us to specify the exact intended behavior of the protocol without needing to deal simultaneously with gas optimization; maintaining equivalent behavior of both serves as a substantial extra form of testing. The behavior of each contract in `p1` should be _identical_ to the behavior of the corresponding contract in `p0`, so we can perform [differential testing](https://en.wikipedia.org/wiki/Differential_testing) between them - checking that they behave identically, both in our explicit tests and in arbitrary randomized tests. We thought `p0` and `p1` would end up being a lot more different than they ended up being. For the most part the contracts only really differ for `StRSR.sol`, and a little for `RToken.sol`. @@ -83,7 +83,7 @@ P1 is the production version of the economic protocol. - Upgradable - Optimized for gas costs - No function call needs more than _O(lg N)_ time or space, and it's _O(1)_ where possible. - - Caveat: a function might be _O(k)_, where _k_ is the number of registered Assets or Collateral tokens; however, we take great care to make those loops efficient, and to avoid _O(k^2)_ behvior! + - Caveat: a function might be _O(k)_, where _k_ is the number of registered Assets or Collateral tokens; however, we take great care to make those loops efficient, and to avoid _O(k^2)_ behavior! - No user is ever forced to pay gas to process other users' transactions. ## Repository Structure diff --git a/docs/collateral.md b/docs/collateral.md index e6ae0e039..9a98938c2 100644 --- a/docs/collateral.md +++ b/docs/collateral.md @@ -97,7 +97,7 @@ interface ICollateral is IAsset { /// @dev refresh() /// Refresh exchange rates and update default status. - /// VERY IMPORTANT: In any valid implemntation, status() MUST become DISABLED in refresh() if + /// VERY IMPORTANT: In any valid implementation, status() MUST become DISABLED in refresh() if /// refPerTok() has ever decreased since last call. /// @return The canonical name of this collateral's target unit. @@ -122,7 +122,7 @@ interface ICollateral is IAsset { Broadly speaking there are two ways a collateral can default: 1. Fast: `refresh()` detects a clear problem with its defi protocol, and triggers in an immediate default. For instance, anytime the `refPerTok()` exchange rate falls between calls to `refresh()`, the collateral should immediately default. -2. Slow: `refresh()` detects a error condition that will _probably_ recover, but which should cause a default eventually. For instance, if the Collateral relies on USDT, and our price feed says that USDT trades at less than \$0.95 for (say) 24 hours, the Collateral should default. If a needed price feed is out-of-date or reverting for a similar period, the Collateral should default. +2. Slow: `refresh()` detects an error condition that will _probably_ recover, but which should cause a default eventually. For instance, if the Collateral relies on USDT, and our price feed says that USDT trades at less than \$0.95 for (say) 24 hours, the Collateral should default. If a needed price feed is out-of-date or reverting for a similar period, the Collateral should default. In either of these cases, the collateral should first become `IFFY` and only move to `DISABLED` after the problem becomes sustained. In general, any pathway for default that cannot be assessed immediately should go through this delayed flow. diff --git a/docs/deployment.md b/docs/deployment.md index 98c96678e..4e0fb1038 100644 --- a/docs/deployment.md +++ b/docs/deployment.md @@ -2,7 +2,7 @@ Mostly, this is about _test_ deployment, though the same elements should work to deploy to any network once configured. -Real mainnet deployment, though, will entail an deployment checklist (see below) and serious operational security considerations (not yet articulated). +Real mainnet deployment, though, will entail a deployment checklist (see below) and serious operational security considerations (not yet articulated). ## Configure Environment @@ -146,7 +146,7 @@ First, clear any stale `*-tmp-*.json` deployment files if it's important for the Do NOT screenshare this part! -It's important that nobody know the deployment key between steps 1 and 2 of the FacadeWrite: `phase3-rtoken/1_deploy_rtoken.ts` and `phase3-rtoken/2_deploy_governance.ts`. But beyond this, we do not require the deployment key to be highly secured. The key will need to hold a decent amount of ETH in order to pay for deployment (estimate: at minimum 3 ETH at 30 gwei) and we certainly do not want someone to come in and snipe our deployment between the FacadeWrite steps, causing us to have to start the FacadeWrite steps again. +It's important that nobody knows the deployment key between steps 1 and 2 of the FacadeWrite: `phase3-rtoken/1_deploy_rtoken.ts` and `phase3-rtoken/2_deploy_governance.ts`. But beyond this, we do not require the deployment key to be highly secured. The key will need to hold a decent amount of ETH in order to pay for deployment (estimate: at minimum 3 ETH at 30 gwei) and we certainly do not want someone to come in and snipe our deployment between the FacadeWrite steps, causing us to have to start the FacadeWrite steps again. First, make sure you have golang setup on your machine. If you don't, here are the quick steps: diff --git a/docs/dev-env.md b/docs/dev-env.md index 02aec1e64..40ca0d336 100644 --- a/docs/dev-env.md +++ b/docs/dev-env.md @@ -30,7 +30,7 @@ npm install -g yarn # Clone this repo git clone git@github.com:reserve-protocol/protocol.git -# Install pacakges from npm (including Solidity dependencies) +# Install packages from npm (including Solidity dependencies) cd protocol yarn @@ -101,7 +101,7 @@ However, ensure that you do not change the value of `.husky/pre-push` in our sha ## Echidna -We _have_ some tooling for testing with Echidna, but it is specically in `fuzz` branch of the repo. See that branch and our [echidna usage docs](using-echidna.md) +We _have_ some tooling for testing with Echidna, but it is specifically in `fuzz` branch of the repo. See that branch and our [echidna usage docs](using-echidna.md) ## Test Deployment diff --git a/docs/exhaustive-tests.md b/docs/exhaustive-tests.md index 5fafdb48f..08fe0fa8c 100644 --- a/docs/exhaustive-tests.md +++ b/docs/exhaustive-tests.md @@ -1,6 +1,6 @@ # Exhaustive Testing -The exhaustive tests include `Broker.test.ts`, `Furnace.test.ts`, `RToken.test.ts`, `ZTradingExtremes.test.ts` and `ZZStRSR.test.ts`, and are meant to test the protocol when given permutations of input values on the extreme ends of the spectrum of possiblities. +The exhaustive tests include `Broker.test.ts`, `Furnace.test.ts`, `RToken.test.ts`, `ZTradingExtremes.test.ts` and `ZZStRSR.test.ts`, and are meant to test the protocol when given permutations of input values on the extreme ends of the spectrum of possibilities. The env vars related to exhaustive testing are `EXTREME` and `SLOW`. diff --git a/docs/mev.md b/docs/mev.md index f0579c8c3..39bb91e0f 100644 --- a/docs/mev.md +++ b/docs/mev.md @@ -1,6 +1,6 @@ # MEV -This document is intended to serve as a resource for MEV searchers and others looking to interact with the deployed protocol programatically. +This document is intended to serve as a resource for MEV searchers and others looking to interact with the deployed protocol programmatically. ## Overview @@ -55,7 +55,7 @@ For a sample price curve, see [docs/system-design.md](./system-design.md#sample- #### GnosisTrade -`GnosisTrade.sol` implements a batch auction on top of Gnosis's [EasyAuction](https://github.com/gnosis/ido-contracts/blob/main/contracts/EasyAuction.sol) platform. In general a batch auction is designed to minimize MEV, and indeed that's why it was chosen in the first place. Both types of auctions (batch + dutch) can be opened at anytime, but the expectation is that dutch auctions will be preferred by MEV searchers because they are more likely to be profitable. +`GnosisTrade.sol` implements a batch auction on top of Gnosis's [EasyAuction](https://github.com/gnosis/ido-contracts/blob/main/contracts/EasyAuction.sol) platform. In general a batch auction is designed to minimize MEV, and indeed that's why it was chosen in the first place. Both types of auctions (batch + dutch) can be opened at any time, but the expectation is that dutch auctions will be preferred by MEV searchers because they are more likely to be profitable. However, if a batch auction is launched, an MEV searcher may still be able to profit. In order to bid in the auction, the searcher must call `function placeSellOrders(uint256 auctionId, uint96[] memory _minBuyAmounts, uint96[] memory _sellAmounts, bytes32[] memory _prevSellOrders, bytes calldata allowListCallData)`, providing an approval in advance. This call will escrow `_sellAmounts` tokens in EasyAuction for the remaining duration of the auction. Once the auction is over, anyone can settle the auction directly in EasyAuction via `settleAuction(uint256 auctionId)`, or by calling `settleTrade(IERC20 erc20)` on the `ITrading` instance in our system that started the trade (either BackingManager or a RevenueTrader). diff --git a/docs/pause-freeze-states.md b/docs/pause-freeze-states.md index 17b2785fc..714bc51db 100644 --- a/docs/pause-freeze-states.md +++ b/docs/pause-freeze-states.md @@ -45,7 +45,7 @@ The issuance-paused states indicates that RToken issuance should be paused, and ## Trading-pause -The trading-paused state has significantly more scope than the issuance-paused state. It is designed to prevent against cases where the protocol may trade unneccesarily. Many other functions in addition to just `BackingManager.rebalance()` and `RevenueTrader.manageTokens()` are halted. In general anything that manages the backing and revenue for an RToken is halted. This may become neccessary to use due to (among other things): +The trading-paused state has significantly more scope than the issuance-paused state. It is designed to prevent against cases where the protocol may trade unnecessarily. Many other functions in addition to just `BackingManager.rebalance()` and `RevenueTrader.manageTokens()` are halted. In general anything that manages the backing and revenue for an RToken is halted. This may become necessary to use due to (among other things): - An asset's `price()` malfunctions or is manipulated - A collateral's default detection has a false positive or negative @@ -58,7 +58,7 @@ An important function of freezing is to provide a finite time for governance to ### `Furnace.melt()` -It is necessary for `Furnace.melt()` to remain emabled in order to allow `RTokenAsset.refresh()` to update its `price()`. Any revenue RToken that has already accumulated at the Furnace will continue to be melted, but the flow of new revenue RToken into the contract is halted. +It is necessary for `Furnace.melt()` to remain enabled in order to allow `RTokenAsset.refresh()` to update its `price()`. Any revenue RToken that has already accumulated at the Furnace will continue to be melted, but the flow of new revenue RToken into the contract is halted. ### `StRSR.payoutRewards()` @@ -66,7 +66,7 @@ It is necessary for `StRSR.payoutRewards()` to remain enabled in order for `StRS ### `StRSR.stake()` -It is important for `StRSR.stake()` to remain emabled while frozen in order to allow honest RSR to flow into an RToken to vote against malicious governance proposals. +It is important for `StRSR.stake()` to remain enabled while frozen in order to allow honest RSR to flow into an RToken to vote against malicious governance proposals. ### `*.settleTrade()` diff --git a/docs/recollateralization.md b/docs/recollateralization.md index 06cf83659..32ddb9c97 100644 --- a/docs/recollateralization.md +++ b/docs/recollateralization.md @@ -38,7 +38,7 @@ As trades complete, the distance between the top and bottom of the BU price band In the optimistic case we assume we start with `basketsHeldBy(backingManager).top` basket units and deduct from this the balance deficit for each backing collateral in terms of basket units (converted optimistically). For deficits we assume the low sell price and high basket unit price. We assume no impact from maxTradeSlippage or minTradeVolume dust loss. Finally we add-in contributions from all surplus balances, this time assuming the high sell price and low basket unit price. -Alltogether, this is how many BUs we would end up with after recapitalization if everything went as well as possible. +Altogether, this is how many BUs we would end up with after recapitalization if everything went as well as possible. #### `basketRange.bottom` @@ -52,7 +52,7 @@ The BU price band is used in order to determine token surplus/deficit: token sur This allows the protocol to deterministically select the next trade based on the following set of constraints (in this order of consideration): -1. Always sell more than than the [`minTradeVolume`](system-design.md#minTradeVolume) governance param +1. Always sell more than the [`minTradeVolume`](system-design.md#minTradeVolume) governance param 2. Never sell more than the [`maxTradeVolume`](system-design.md#rTokenMaxTradeVolume) governance param 3. Sell `DISABLED` collateral first, `SOUND` next, and `IFFY` last. (Non-collateral assets are considered SOUND for these purposes.) diff --git a/docs/solidity-style.md b/docs/solidity-style.md index 90b386b82..1ff39574d 100644 --- a/docs/solidity-style.md +++ b/docs/solidity-style.md @@ -20,13 +20,13 @@ Throughout our system, any variable in state or memory, function parameter, or r These operations mostly come in a few classes: -- Conversion operations between Fix and and regular `uint` values: `toFix` and `toUint` +- Conversion operations between Fix and regular `uint` values: `toFix` and `toUint` - Typical numeric operations like `plus`, `minus`, `mul`, `div`, `pow`, `lt`, `eq`, and so on - Typical operations between Fix and unsigned int values, which have a `u` appended: `plusu`, `minusu`, `mulu`, `divu` - A few special-case operations, inferrable from their datatypes. (For instance, `divuu(uint256 x, uint256 y) pure returns (uint192)` takes two unsigned integer values and returns their ratio as a Fix value, and `divFix(uint256 x, uint192 y) pure returns (uint192)` divides a Fix by an unsigned int, returning a Fix value. - Chained operations, like `mulu_toUint` or `muluDivu`, which just to perform those operations in sequence. -Criticially, all of these operations are written so that they only fail with overflow errors if their result is outside the range of the return type. This is what motivates the chained operations, which are typically more expensive than their unchained analogues, but which do whatever work is necessary to avoid intermediate overflow. For instance: +Critically, all of these operations are written so that they only fail with overflow errors if their result is outside the range of the return type. This is what motivates the chained operations, which are typically more expensive than their unchained analogues, but which do whatever work is necessary to avoid intermediate overflow. For instance: ```solidity uint192 one = FIX_ONE; @@ -59,7 +59,7 @@ We don't have static checking for the following properties, so we have to mainta Outside of Fixed.sol: - NEVER allow a `uint192` to be implicitly upcast to `uint256`, without a comment explaining what is happening and why. -- NEVER explcitily cast between `uint192` and `uint256` without doing the appropriate numeric conversion (e.g, `toUint()` or `toFix()`.) +- NEVER explicitly cast between `uint192` and `uint256` without doing the appropriate numeric conversion (e.g, `toUint()` or `toFix()`.) - ONLY use standard arithmetic operations on `uint192` values IF: - you're gas-optimizing a hotspot in P1 and need to remove Fixlib calls - in inline comments, you explain what you're doing and why @@ -86,7 +86,7 @@ Throughout our code, we use [dimensional analysis][] to guard against mistakes o ### Developer discipline - All declarations of state variables and interface parameters that represent a value with one of the above dimensions MUST have a comment naming their unit. -- Wherever those values are used in assignments in our code, the sides of the assignemnt MUST have the same dimensions. +- Wherever those values are used in assignments in our code, the sides of the assignment MUST have the same dimensions. - Amid complex arithmetic, that the dimension are the same SHOULD be demonstrated in a nearby comment. [atto]: https://en.wikipedia.org/wiki/Atto- @@ -147,7 +147,7 @@ All execution flows through the protocol should contain at most a single (1) act Functions that are not system-external, but are `external` and can be called by other contracts in the system, are tagged with `@custom:protected`. It is governance's job to ensure a malicious contract is never allowed to masquerade as a component and call one of these. They do not execute when paused. -For each `external` or `public` function, one of these tags MUST be in the correponding function's natSpec comments. We don't have a static checker for this property, but it needs to be maintained by all developers. +For each `external` or `public` function, one of these tags MUST be in the corresponding function's natSpec comments. We don't have a static checker for this property, but it needs to be maintained by all developers. ### `@custom:interaction` @@ -228,7 +228,7 @@ Anything that doesn't fit these two policies precisely must be carefully and ful - `RewardableLib.claimRewards()` -- The entire `GnosisTrade` contract is using the moral equivalent of `ReentrancyGuard` to ensure its own reentrancy-safety, but since it's also using the state machine pattern, it can do both with the same state varible and save gas on SLOADs and SSTOREs. +- The entire `GnosisTrade` contract is using the moral equivalent of `ReentrancyGuard` to ensure its own reentrancy-safety, but since it's also using the state machine pattern, it can do both with the same state variable and save gas on SLOADs and SSTOREs. ### Reentrancy risk from collateral @@ -267,7 +267,7 @@ try chainlinkFeed.price_(oracleTimeout) returns (uint192 p) { } ``` -Notice, though, that we're _not_ going IFFY when `errData` is empty, but instead just reverting with another empty error. Why? Well, it's not very well-documented (and honestly it feels like a likely candidate for future change in the EVM), but the EVM emits a error with empty low-level data if it hits an out-of-gas error. This is an issue for us, though, because if the collateral contract goes IFFY on any out-of-gas error, then an attacker can set a collateral contract to IFFY at will, just by crafting an otherwise-legitimate transaction targeted to run out of gas during the `chainlinkFeed.price_()` call. +Notice, though, that we're _not_ going IFFY when `errData` is empty, but instead just reverting with another empty error. Why? Well, it's not very well-documented (and honestly it feels like a likely candidate for future change in the EVM), but the EVM emits an error with empty low-level data if it hits an out-of-gas error. This is an issue for us, though, because if the collateral contract goes IFFY on any out-of-gas error, then an attacker can set a collateral contract to IFFY at will, just by crafting an otherwise-legitimate transaction targeted to run out of gas during the `chainlinkFeed.price_()` call. So, to err on the side of non-griefability, these collateral contracts allow empty errors to pass through, rather than catching them and going IFFY. @@ -277,7 +277,7 @@ Components of production version P1 are designed to be upgradeable using the Pro [proxy-docs]: https://docs.openzeppelin.com/upgrades-plugins/1.x/proxies -This implies that the core contracts in P1 (`Main` and core components) are meant to be deployed as implementation contracts, which will serve as a reference to deploy later specific instances (or "proxies") via the `Deployer` contract. If changes are required in the future, a new implementation version can be deployed and the Proxy can be upgrated to point to this new implementation, while preserving its state and storage. +This implies that the core contracts in P1 (`Main` and core components) are meant to be deployed as implementation contracts, which will serve as a reference to deploy later specific instances (or "proxies") via the `Deployer` contract. If changes are required in the future, a new implementation version can be deployed and the Proxy can be upgraded to point to this new implementation, while preserving its state and storage. ### Writing upgrade-safe contracts @@ -303,7 +303,7 @@ The **recommended** process to perform an upgrade is the following: - Ensure metadata of the existing/deployed implementations is created for the required network. This is located in a folder names `.openzeppelin`, which should be persisted in `git` for Production networks. This can be done for prior versions using the `upgrades/force-import.ts` task in our repository. This task is limited to be run only on Mainnet. -- Create the new implementation version of the contract. This should follow all the recommendations from the article linked above, to make sure the implementation is "Upgrade Safe". At anytime you can check for compatibility by running the `upgrades/validate-upgrade.ts` task in our repo, in a Mainnet fork. This task would compare the current code vs. a previously deployed implementation and validate if it is "upgrade safe". Make sure the FORK_BLOCK is set up appropiately. +- Create the new implementation version of the contract. This should follow all the recommendations from the article linked above, to make sure the implementation is "Upgrade Safe". At any time you can check for compatibility by running the `upgrades/validate-upgrade.ts` task in our repo, in a Mainnet fork. This task would compare the current code vs. a previously deployed implementation and validate if it is "upgrade safe". Make sure the FORK_BLOCK is set up appropriately. - To deploy to Mainnet the new version, make sure you use the script provided in `scripts/deployment/phase1-common/2_deploy_implementations.ts`. If you are upgrading a previous version you need to specify the `LAST_VERSION_DEPLOYED` value at the top of the script. For new, clean deployments just leave that empty. This script will perform all validations on the new code, deploy the new implementation contracts, and register the deployment in the network file. It relies on the `deployImplementation` (for new deployments) or `prepareUpgrade` functions of the OZ Plugin. @@ -325,7 +325,7 @@ Here, "contract state" refers to the normal storage variables of a smart contrac - P1 core contracts MUST NOT set state variables in their constructor. - P1 core contracts MUST NOT initialize state variables where they are declared. -Instead of any of these, P1 core contracts will probably each define an initializer funcion, per the usual OZ upgradability pattern. A P1 core contract MAY depend on that initializer having run before any other functions. +Instead of any of these, P1 core contracts will probably each define an initializer function, per the usual OZ upgradability pattern. A P1 core contract MAY depend on that initializer having run before any other functions. ### Storage Gaps diff --git a/docs/system-design.md b/docs/system-design.md index a2116c359..22128c989 100644 --- a/docs/system-design.md +++ b/docs/system-design.md @@ -44,7 +44,7 @@ The protocol (weakly) assumes a 12-second blocktime. This section documents the #### Should-be-changed if blocktime different -- The `Furnace` melts RToken in periods of 12 seconds. If the protocol is deployed to a chain with shorter blocktime, it is possible it may be rational to issue right before melting and redeem directly after, in order to selfishly benefit. The `Furnace` shouild be updated to melt more often. +- The `Furnace` melts RToken in periods of 12 seconds. If the protocol is deployed to a chain with shorter blocktime, it is possible it may be rational to issue right before melting and redeem directly after, in order to selfishly benefit. The `Furnace` should be updated to melt more often. #### Probably fine if blocktime different @@ -119,7 +119,7 @@ For instance, if the reference basket contains the pair ``, then on This is the form of the basket that recipients and redeemer will care most about. Issuance and redemption quantities are given by the collateral basket times the current `rTok/BU` exchange rate. -While an issuance is pending in the mempool, the quantities of tokens that will be ingested when the transaciton is mined may decrease slightly as the collateral becomes worth more. If furnace melting happens in that time, however, this can increase the quantity of collateral tokens in the basket and cause the issuance to fail. +While an issuance is pending in the mempool, the quantities of tokens that will be ingested when the transaction is mined may decrease slightly as the collateral becomes worth more. If furnace melting happens in that time, however, this can increase the quantity of collateral tokens in the basket and cause the issuance to fail. On the other hand, while a redemption is pending in the mempool, the quantities of collateral tokens the redeemer will receive steadily decreases. If a furnace melting happens in that time the quantities will be increased, causing the redeemer to get more than they expected. @@ -140,7 +140,7 @@ Non-owner roles: Design intentions: - The PAUSER role should be assigned to an address that is able to act quickly in response to off-chain events, such as a Chainlink feed failing. It is acceptable for there to be false positives, since redemption remains enabled. -- The SHORT_FREEZER role should be assigned to an address that might reasonably be expected to be the first to detect a bug in the code and can act quickly, and with some tolerance for false positives though less than in pausing. If a bug is detected, a short freeze can be triggered which will automatically expire if it is not renewed by LONG_FREEZER. The OWNER (governance) may also step in and unfreeze at anytime. +- The SHORT_FREEZER role should be assigned to an address that might reasonably be expected to be the first to detect a bug in the code and can act quickly, and with some tolerance for false positives though less than in pausing. If a bug is detected, a short freeze can be triggered which will automatically expire if it is not renewed by LONG_FREEZER. The OWNER (governance) may also step in and unfreeze at any time. - The LONG_FREEZER role should be assigned to an address that will highly optimize for no false positives. It is much longer than the short freeze. It exists so that in the case of a zero-day exploit, governance can act before the system unfreezes and resumes functioning. ## System Auctions @@ -152,7 +152,7 @@ The Reserve Protocol makes a few different types of trades: - collateral to collateral, in order to change the distribution of collateral due to a basket change. Basket changes should be rare, happening only when governance changes the basket, or when some collateral token defaults. This only happens in the BackingManager. - RSR to collateral, in order to recollateralize the protocol from stRSR over-collateralization, after a basket change. These auctions should be even rarer, happening when there's a basket change and insufficient capital to achieve recollateralization without using the over-collateralization buffer. These auctions also happen in the BackingManager. -Each type of trade can happen two ways: either by a falling-price ductch auction (DutchTrade) or by a batch auction via Gnosis EasyAuction (GnosisTrade). More trading methods can be added in the future. +Each type of trade can happen two ways: either by a falling-price dutch auction (DutchTrade) or by a batch auction via Gnosis EasyAuction (GnosisTrade). More trading methods can be added in the future. ### Gnosis EasyAuction Batch Auctions (GnosisTrade) diff --git a/docs/using-echidna-on-gcp.md b/docs/using-echidna-on-gcp.md index 5f60910c1..f2106887c 100644 --- a/docs/using-echidna-on-gcp.md +++ b/docs/using-echidna-on-gcp.md @@ -67,7 +67,7 @@ pip3 install solc-select slither_analyzer echidna_parade # Maybe overkill, but it won't take too long solc-select install all -# Install node. Use the snap, instead of the apt pacakge, to avoid installing +# Install node. Use the snap, instead of the apt package, to avoid installing # _way too much_ other junk sudo snap install node --classic --channel=16 diff --git a/docs/using-echidna.md b/docs/using-echidna.md index 0d27cb527..031f31976 100644 --- a/docs/using-echidna.md +++ b/docs/using-echidna.md @@ -1,6 +1,6 @@ # Echidna -> Echidna is a Haskell program designed for fuzzing/property-based testing of Ethereum smarts contracts. It uses sophisticated grammar-based fuzzing campaigns based on a contract ABI to falsify user-defined predicates or Solidity assertions. +> Echidna is a Haskell program designed for fuzzing/property-based testing of Ethereum smart contracts. It uses sophisticated grammar-based fuzzing campaigns based on a contract ABI to falsify user-defined predicates or Solidity assertions. Our usage of Echidna is immature; we've used it only just enough to get a handful of proof-of-concept results, not as a day-to-day part of our toolchain. These notes are useful but preliminary!