GithubHelp home page GithubHelp logo

reserve-protocol / rsv-v2 Goto Github PK

View Code? Open in Web Editor NEW
18.0 7.0 9.0 673 KB

Implementation of a simple crypto-collateralized decentralized stablecoin

License: Other

Makefile 1.42% Go 61.44% JavaScript 1.01% Solidity 30.83% Shell 1.37% Python 2.64% Perl 1.29%

rsv-v2's Introduction

RSV V2

The RSV v2 is a stable token, implemented as a series of Ethereum smart contracts, designed to maintain a stable price on the open market.

Links:

Stale V1 Addresses:

-   Reserve token: [0x1C5857e110CD8411054660F60B5De6a6958CfAE2](https://etherscan.io/address/0x1c5857e110cd8411054660f60b5de6a6958cfae2)
-   Manager: [0x5BA9d812f5533F7Cf2854963f7A9d212f8f28673](https://etherscan.io/address/0x5BA9d812f5533F7Cf2854963f7A9d212f8f28673)

What does it do?

RSV v2 is a standard ERC-20 token with support for upgrades and emergency pausing. Beyond this, the system ensures that it always maintains full backing for the outstanding supply of RSV, in terms of its current basket. Moreover, the system can issue new RSV to a user that provides matching basket assets, allow a user to redeem RSV for basket assets, and process rebalancing proposals that update the assets and weightings of assets in the basket.

RSV v2 is not the version of RSV described in our whitepaper. RSV v2 supports:

  • RSV issuance
  • RSV redemption
  • Vault rebalancing

Key features of Reserve not included in RSV v2 include:

  • Linking RSV to RSR
  • A price feed, which is necessary for RSV to peg to traditional currencies while holding more-volatile assets in its vault
  • Decentralized governance

How does it fit together?

The center of this system are the smart contracts in contracts/ and contracts/rsv.

  • Manager.sol: Handles issuance and redemption of RSV, and vault-rebalancing proposals. Manager is the root of this system's automated permissions; it holds the manager role on Vault and the minter role on Reserve.
  • rsv/Reserve.sol: The actual RSV token.
  • rsv/ReserveEternalStorage.sol: The backing store for RSV, implementing the eternal storage pattern.
  • Vault.sol: The RSV Vault. This contract is very simple; it just allows some manager address make withdrawals. (In the deployed system, that manager is the Manager contract.) Having the Vault contract, instead of just letting the Reserve or Manager contracts store the backing assets, lets us leave the collateral assets at the same address if we upgrade the manager, which is good both for auditing transparency and minimizing transaction overhead.
  • Basket.sol: Essentially just the data structure that represents a set of vault assets, and their weighting per RSV. There is always a current basket, and rebalancing proposals make new potential baskets.
  • Proposal.sol: Actually contains quite a few contracts:
    • Proposal: The base proposal class. A proposal has a state machine describing its current state in the proposal acceptance-or-rejection process, and must implement a function that yields a basket at completion time.
    • WeightProposal: A proposal that yields a static, proposed basket at completion time.
    • SwapProposal: A proposal to exchange specific quantities of specific tokens, and which will compute its precise basket at completion time.
    • ProposalFactory: A factory for new SwapProposals and WeightProposals. This exists instead of the equivalent new statements in Manager, because new in Manager would force Manager over the 24-KB contract bytecode limit due to EIP 170.

For greater technical detail, see the source code itself -- each of these contracts' interfaces are generally documented in detail there.

Environment Setup

To build and test these contracts, your development environment will need:

  • Make
  • Go 1.12 or later
  • Either solc-select, or a manual installation of solc version 0.5.7
  • slither, for basic source analysis.

Specific further makefile targets assume some other tools:

  • The mythril target, in order to perform security analyses using symbolic execution, requires a mythril installation. This installation usually takes some patience and fiddling; and it's not critical for working with these contracts.
  • The run-geth target launches a local ethereum chain suitable for testing. It requires a working docker installation on your development machine.
  • The sizes target assumes that you have jq, and a bunch of standard Unix utilities (sed, awk, tr, and sort) installed.

Building and Testing

The whole build-and-test workflow is automated in the makefile. Just running make will build everything and run basic tests; the default make target is a good default, in-development, build-and-test feedback loop.

  • make json: Build just the smart contracts, outputs in evm/
  • make abi: Build the smart-contract Go bindings, outputs in abi/
  • make test: Build contract, run normal tests.
  • make clean: Clean up built artifacts in this directory.
  • make fuzz: Run a short round of fuzz testing. (Tinker with the command this target invokes for larger or different fuzz-test runs.
  • make sizes: Output the current sizes of each contract's bytecode, in bytes. (Useful when you're trying out bytecode-size optimizations, which is important for staying under the 24KB bytecode size limit.)
  • make flat: Produce flattened Solidity files, as is useful for getting that deployed code verified on Etherscan, or playing with it inside Remix.
  • make check: Do analysis of smart contracts with slither.
  • make triage-check: Like make check, but runs slither in triage mode, which you can use to suppress specific reports in future runs.
  • make run-geth: Launch a local Ethereum chain for smart contract tinkering. Tools for that interaction are not included here; we use poke for this.
  • make -j1 mythril: Run mythril on these smart contracts. The -j1 flag is necessary if you have make set up to run in parallel by default (do this!), because mythril does not really support being run in parallel. This is sort of fine, because a single instance of mythril will eat all your cores and still be hungry, but it is something extra to remember when you call it.

Directory Layout

Contents of this repository:

  • contracts/: Actual smart contract source; the point of this repo.
  • tests/: Set of tests, in Go, exercising our smart contracts.
  • soltools/: Contains some test dependencies (that we haven't moved into tests/).
  • design-docs/: Documentation and scratch notes. Most of this is really drafty notes from our team to our team. It's not really intended to be comprehensible to passersby. but it might be useful for understanding some of the considerations behind the design of these contracts.
  • go.mod, go.sum: Files for using this directory as a Go module.
  • genABI.go: A Go script for generating Go bindings for Solidity smart contracts.
  • scripts/sizes: The shell script to compute bytecode sizes, run by make sizes.
  • slither.db.json: The Slither triage file.
  • Makefile: The makefile; automates workflow steps.
  • README.md: The file you're reading now.
  • LICENSE: The license file. (We're using the Blue Oak Model License, and it's quite possible that you should, too!)

Brownie

Getting brownie

python3 -m pip install --user pipx python3 -m pipx ensurepath pipx install eth-brownie

Setting up the required brownie network

brownie networks add Development short-lived gas_limit=12000000 mnemonic=brownie chainid=17

rsv-v2's People

Contributors

fiddlemath avatar puremachinery avatar tbrent avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

rsv-v2's Issues

Enrich makefile

In general, ensure that make is actually able to do its dependency-tracking-and-caching magic:

  • Use PHONY to mark "fake" targets (e.g., all the current ones)
  • Use normal rules to mark workflow targets (e.g., evm/%.json:)
  • Ensure that make test runs all our validation mechanisms, including normal tests, static checking (slither, mythril, oyente), and fuzzing.
  • Build up a make dev-deploy target, for fast local interaction.

Missing functionality: The basket is never updated.

Currently, Manager never updates its Basket after a Proposal is executed. It should.

There is some difficulty here. The case to consider is the following:

  • Say the basket is currently [A, B] in some quantity. (where A and B are tokens)
  • A new "percentage proposal" is submitted, for [A, B, C].
  • A "quantity proposal" is submitted. Since quantity proposals only contain a list of quantities to be exchanged, and assume the current set of tokens, this quantity proposal is saved as being for [A, B].
  • Both proposals are accepted.
  • 24 hours passes and the "percentage proposal" is executed, adding C to the Vault.
  • "quantity proposal" is executed, reverting the backing to [A, B].

One option is to wait to submit the "quantity proposal" until after the "percentage proposal" is executed and C has been added to the Vault. But this doubles the lower bound on how quickly we can complete a series of rebalances, and also makes it possible to make mistakes as the operator.

In general, we need to update the basket after proposal execution, and while doing so, I think we should ensure that in the case above, the final basket results in [A, B, C] rather than [A, B].

Determine design for txn fees, if any

If we have transfer fees in the future, what behavior do we actually want? Some sane options:

Option 1: transfer(recipient, value) deducts the fee from value:

  • balanceOf(msg.sender) -= value
  • balanceOf(recipient) += value - fee
  • balanceOf(feeTaker) += fee

Option 2: transfer(recipient, value) passes all of value to the recipient, and the sender pays a bit more:

  • balanceOf(msg.sender) -= value + fee
  • balanceOf(recipient) += value
  • balanceOf(feeTaker) += fee

Pros and cons:

  • In Option 1, you can cleanly transfer out the entire balance of an account. In Option 2, this would require computing just the right value such that value + fee equals the balance that you intend.
  • In Option 2, you can cleanly pay an exact amount to a recipient that requires that they wind up with a specific balance. In Option 1, this would, again, require the sender to compute just the right value based on the fee schedule.
  • Option 2 seems to more closely follow ERC-20, where the definition of transfer includes that it "Transfers _value tokens to address _to." Nowhere does it say that it transfers _value tokens away from the sender's address.

Option 3: In light of this, it seems to me that the ideal solution is to support both options as separate functions, where Option 2 gives the semantics of the transfer function, and Option 1 is implemented under some similar name (relocate? send?). Or, perhaps Option 4, where transfer is implemented only as in Option 2, and we implement transferAll(recipient) specifically for the case where someone wants to transfer all of their tokens.

contracts/test/BasicOwnable.sol shouldn't need to exist

Ownable is not an abstract contract, so we shouldn't 'need a separate contract to trivially dervie from it as contracts/test/BasicOwnable.sol does.

So, we should either figure out why we do want or need this testing contract, or just get rid of it.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.