All Projects → dapphub → Chai

dapphub / Chai

Licence: agpl-3.0
ERC20 wrapper over the Dai Savings Rate

Programming Languages

solidity
1140 projects

Labels

Projects that are alternatives of or similar to Chai

match-screenshot
A simple Jest or Chai matcher to compare screenshots, using Applitools Eyes
Stars: ✭ 14 (-88.14%)
Mutual labels:  chai
Tvrboreact
Dream starter project: React, Redux, React Router, Webpack
Stars: ✭ 13 (-88.98%)
Mutual labels:  chai
Preact Jsx Chai
✅ Add JSX assertions to Chai, with support for Preact Components.
Stars: ✭ 56 (-52.54%)
Mutual labels:  chai
stablecoin.services
A gas free offering of common Dai and Chai operations
Stars: ✭ 32 (-72.88%)
Mutual labels:  chai
Node Express Mongodb Jwt Rest Api Skeleton
This is a basic API REST skeleton written on JavaScript using async/await. Great for building a starter web API for your front-end (Android, iOS, Vue, react, angular, or anything that can consume an API). Demo of frontend in VueJS here: https://github.com/davellanedam/vue-skeleton-mvp
Stars: ✭ 603 (+411.02%)
Mutual labels:  chai
Chakram
REST API test framework. BDD and exploits promises
Stars: ✭ 912 (+672.88%)
Mutual labels:  chai
express-mysql-rest
Building the simple api with sequelize, mysql and express js. this repository contains the code about how to use sequelize with mysql at express js. for example i have provide the crud operation to this repository. You can also testing the api with chai and mocha with chai-http by this repository
Stars: ✭ 25 (-78.81%)
Mutual labels:  chai
Karma Webpack Example
Karma + Webpack + Mocha + Chai + Istanbul
Stars: ✭ 88 (-25.42%)
Mutual labels:  chai
Jest Codemods
Codemods for migrating to Jest https://github.com/facebook/jest 👾
Stars: ✭ 731 (+519.49%)
Mutual labels:  chai
Bombanauts
Bombanauts, inspired by the original Bomberman game, is a 3D multiplayer online battle arena (MOBA) game where players can throw bombs at each other, make boxes explode, and even other players!
Stars: ✭ 54 (-54.24%)
Mutual labels:  chai
Enzyme
JavaScript Testing utilities for React
Stars: ✭ 19,781 (+16663.56%)
Mutual labels:  chai
React Progressive Web App
An opinionated React based repository which is optimized for Progressive Web App development.
Stars: ✭ 548 (+364.41%)
Mutual labels:  chai
Koa Typescript Starter
Integrating TypeScript with KOA2 to hit the ground running faster
Stars: ✭ 51 (-56.78%)
Mutual labels:  chai
nodejs-application-architecture
👨‍🔧 A discussion on how Node.js projects can be organized.
Stars: ✭ 81 (-31.36%)
Mutual labels:  chai
Openapivalidators
Use Jest or Chai to assert that HTTP responses satisfy an OpenAPI spec
Stars: ✭ 77 (-34.75%)
Mutual labels:  chai
chai-passport-strategy
Helpers for testing Passport strategies with the Chai assertion library.
Stars: ✭ 32 (-72.88%)
Mutual labels:  chai
Jobsort
job board that queries hacker news who is hiring job listings from a database and sorts by tech the user knows and how well the user knows them
Stars: ✭ 20 (-83.05%)
Mutual labels:  chai
Typescript Restful Starter
Node.js + ExpressJS + Joi + Typeorm + Typescript + JWT + ES2015 + Clustering + Tslint + Mocha + Chai
Stars: ✭ 97 (-17.8%)
Mutual labels:  chai
React Base
atSistemas React/Redux Isomorphic Platform
Stars: ✭ 82 (-30.51%)
Mutual labels:  chai
Aws Testing Library
Chai (https://chaijs.com) and Jest (https://jestjs.io/) assertions for testing services built with aws
Stars: ✭ 52 (-55.93%)
Mutual labels:  chai

🍵

1 Chai = 1 Dai * Pot.chi

chai is an ERC20 token representing a claim on deposits in the DSR. It can be freely converted to and from dai: the amount of dai claimed by one chai is always increasing, at the Dai Savings Rate. Like any well-behaved token, a user's chai balance won't change unexpectedly, while the chai's value grows day by day.

chai is a very simple contract. Apart from the standard ERC20 functionality, it also implements the same permit off-chain approval as dai itself. You can also call dai(address usr) to check how many dai a given user's chai balance claims. The token has no owner or authority. That's all there is to it.

mainnet deployment

chai is live on the mainnet since December 1st at 0x06af07097c9eeb7fd685c692751d5c66db49c215

You can interact with the Chai contract at chai.money. The source for the ui is hosted here.

audit

The deployed chai contract underwent a two day audit by Trail Of Bits in the beginning of February, finding no security related issues. A summary can be found here.

building and testing

This contract is built using dapptools, and follows the standard dapptools procedure for building and testing.

To compile:

$ make all

To run the tests:

$ make test

documentation

ERC20 functions

Chai.sol implements the standard ERC20 functions (balanceOf, allowance, approve, transfer, transferFrom).

Similar to tokens like WETH, MKR and DAI, an allowance of uint(-1) is treated as "infinity", so transferFrom calls from an address that has been given an allowance of uint(-1) will not cause the allowance to decrease.

Join

The chai contract is an ERC20 token where minting happens in a function called join, which converts a users Dai balance into Chai:

    function join(address dst, uint wad) external {
        uint chi = (now > pot.rho()) ? pot.drip() : pot.chi();
        uint pie = rdiv(wad, chi);
        balanceOf[dst] = add(balanceOf[dst], pie);
        totalSupply    = add(totalSupply, pie);

        daiToken.transferFrom(msg.sender, address(this), wad);
        daiJoin.join(address(this), wad);
        pot.join(pie);
        emit Transfer(address(0), dst, pie);
    }

Calling this function transfers wad Dai into the pot contract from msg.sender, granting the dst address a Chai balance representing their claim of Dai in the pot contract.

Exit

Chai is burned (converted into Dai) through a function called exit:

    function exit(address src, uint wad) public {
        require(balanceOf[src] >= wad, "chai/insufficient-balance");
        if (src != msg.sender && allowance[src][msg.sender] != uint(-1)) {
            require(allowance[src][msg.sender] >= wad, "chai/insufficient-allowance");
            allowance[src][msg.sender] = sub(allowance[src][msg.sender], wad);
        }
        balanceOf[src] = sub(balanceOf[src], wad);
        totalSupply    = sub(totalSupply, wad);

        uint chi = (now > pot.rho()) ? pot.drip() : pot.chi();
        pot.exit(wad);
        daiJoin.exit(msg.sender, rmul(chi, wad));
        emit Transfer(src, address(0), wad);
    }

A msg.sender with sufficient approval from the address src can call this function to decrease their Chai balance by wad and transfer its underlying Dai value to the msg.sender.

Draw

Since the wad argument to the exit function above is denominated in chai, the exact Dai transferred will be determined at the time the transaction is included in a block. If you want to ensure that a specific Dai amount must be transfered, you can use the draw function instead, which takes a dai denominated argument:

    // wad is denominated in dai
    function draw(address src, uint wad) external {
        uint chi = (now > pot.rho()) ? pot.drip() : pot.chi();
        // rounding up ensures usr gets at least wad dai
        exit(src, rdivup(wad, chi));
    }

Move

Similarly to draw, there is a transferFrom function with a dai denominated argument, ensuring that the receiving address will receive Chai worth at least wad dai:

    // like transferFrom but dai-denominated
    function move(address src, address dst, uint wad) external returns (bool) {
        uint chi = (now > pot.rho()) ? pot.drip() : pot.chi();
        // rounding up ensures dst gets at least wad dai
        return transferFrom(src, dst, rdivup(wad, chi));
    }

Permit

The permit method lets a user approve an address to spend on their behalf by signing a ERC712 typed message called permit.

A permit consists of the following components:

  • holder, the address granting the permission and the signer of the message
  • spender, the address to which permission is being granted or denied
  • nonce, for replay attack protection
  • allowed, whether the spenders permission is being granted or revoked

Messages are signed using the procedure described in ERC712, using the PERMIT_TYPEHASH and DOMAIN_SEPARATOR constants:

    bytes32 public constant DOMAIN_SEPARATOR = 0x0b50407de9fa158c2cba01a99633329490dfd22989a150c20e8c7b4c1fb0fcc3;
    // keccak256("Permit(address holder,address spender,uint256 nonce,uint256 expiry,bool allowed)"));
    bytes32 public constant PERMIT_TYPEHASH  = 0xea2aa0a1be11a07ed86d755c93467f4f82362b452371d1ba94d1715123511acb;

permit are processed by calling the permit method, which increments the holder nonce and approves the spender to spend on the behalf of holder if allowed is true, and revokes it otherwise:

    // --- Approve by signature ---
    function permit(address holder, address spender, uint256 nonce, uint256 expiry, bool allowed, uint8 v, bytes32 r, bytes32 s) external
    {
        bytes32 digest = keccak256(abi.encodePacked(
            "\x19\x01",
            DOMAIN_SEPARATOR,
            keccak256(abi.encode(PERMIT_TYPEHASH,
                                 holder,
                                 spender,
                                 nonce,
                                 expiry,
                                 allowed))));
        require(holder != address(0), "chai/invalid holder");
        require(holder == ecrecover(digest, v, r, s), "chai/invalid-permit");
        require(expiry == 0 || now <= expiry, "chai/permit-expired");
        require(nonce == nonces[holder]++, "chai/invalid-nonce");

        uint can = allowed ? uint(-1) : 0;
        allowance[holder][spender] = can;
        emit Approval(holder, spender, can);
    }
Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].